├── .dockerignore ├── .gitignore ├── .rspec ├── .rubocop.yml ├── .rubocop_todo.yml ├── .ruby-gemset ├── .ruby-version ├── .simplecov ├── .travis.yml ├── CONTRIBUTING.md ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Procfile ├── README.md ├── Rakefile ├── config.ru ├── docker-compose.yml ├── example_payloads ├── linux_ruby_cache_bundler.json └── skip.json ├── init.rb ├── je ├── lib ├── core_ext │ ├── hash │ │ ├── compact.rb │ │ ├── deep_merge.rb │ │ └── deep_symbolize_keys.rb │ ├── object │ │ └── false.rb │ └── string │ │ ├── indent.rb │ │ ├── output_safe.rb │ │ ├── to_bool.rb │ │ └── unindent.rb ├── travis.rb └── travis │ ├── api │ └── build │ │ ├── app.rb │ │ ├── metriks.rb │ │ └── sentry.rb │ ├── build.rb │ ├── build │ ├── .travis.yml │ ├── addons.rb │ ├── addons │ │ ├── apt.rb │ │ ├── apt_packages.rb │ │ ├── apt_retries.rb │ │ ├── artifacts.rb │ │ ├── artifacts │ │ │ ├── env.rb │ │ │ └── validator.rb │ │ ├── base.rb │ │ ├── blender.rb │ │ ├── browserstack.rb │ │ ├── chrome.rb │ │ ├── code_climate.rb │ │ ├── coverity_scan.rb │ │ ├── deploy.rb │ │ ├── deploy │ │ │ ├── conditions.rb │ │ │ ├── config.rb │ │ │ └── script.rb │ │ ├── firefox.rb │ │ ├── homebrew.rb │ │ ├── hostname.rb │ │ ├── hosts.rb │ │ ├── jwt.rb │ │ ├── mariadb.rb │ │ ├── pkg.rb │ │ ├── postgresql.rb │ │ ├── rethinkdb.rb │ │ ├── sauce_connect.rb │ │ ├── sbom.rb │ │ ├── sbom │ │ │ └── script.rb │ │ ├── snaps.rb │ │ ├── sonarcloud.rb │ │ ├── sonarqube.rb │ │ ├── srcclr.rb │ │ ├── ssh_known_hosts.rb │ │ └── tensor_flow.rb │ ├── appliances.rb │ ├── appliances │ │ ├── agent.rb │ │ ├── agent │ │ │ ├── agent.rb │ │ │ └── jwt.rb │ │ ├── apt_get_update.rb │ │ ├── base.rb │ │ ├── check_unsupported.rb │ │ ├── checkout.rb │ │ ├── clean_up_path.rb │ │ ├── debug_tools.rb │ │ ├── debug_tools │ │ │ └── templates │ │ │ │ └── tmate.conf.erb │ │ ├── deprecate_xcode_64.rb │ │ ├── deprecations.rb │ │ ├── disable_initramfs.rb │ │ ├── disable_ssh_roaming.rb │ │ ├── disable_sudo.rb │ │ ├── disable_windows_defender.rb │ │ ├── docker_config.rb │ │ ├── enable_i386.rb │ │ ├── ensure_path_components.rb │ │ ├── env.rb │ │ ├── etc_hosts_pinning.rb │ │ ├── fix_container_based_trusty.rb │ │ ├── fix_etc_hosts.rb │ │ ├── fix_etc_mavenrc.rb │ │ ├── fix_hhvm_source.rb │ │ ├── fix_mvn_settings_xml.rb │ │ ├── fix_perforce_key.rb │ │ ├── fix_ps4.rb │ │ ├── fix_resolv_conf.rb │ │ ├── fix_rwky_redis.rb │ │ ├── fix_sudo_enabled_trusty.rb │ │ ├── fix_wwdr_certificate.rb │ │ ├── git_v2.rb │ │ ├── home_paths.rb │ │ ├── maven_central_mirror.rb │ │ ├── maven_https.rb │ │ ├── no_ipv6_localhost.rb │ │ ├── no_world_writable_dirs.rb │ │ ├── nonblock_pipe.rb │ │ ├── npm_registry.rb │ │ ├── put_localhost_first.rb │ │ ├── redefine_curl.rb │ │ ├── resolvconf.rb │ │ ├── rm_etc_boto_cfg.rb │ │ ├── rm_oraclejdk8_symlink.rb │ │ ├── rm_riak_source.rb │ │ ├── rvm_use.rb │ │ ├── services.rb │ │ ├── set_docker_mtu_and_registry_mirrors.rb │ │ ├── set_x.rb │ │ ├── setup_filter.rb │ │ ├── shell_session_update.rb │ │ ├── show_system_info.rb │ │ ├── uninstall_oclint.rb │ │ ├── update_apt_keys.rb │ │ ├── update_glibc.rb │ │ ├── update_heroku.rb │ │ ├── update_libssl.rb │ │ ├── update_mongo_arch.rb │ │ ├── update_rubygems.rb │ │ ├── validate.rb │ │ ├── vault_connect.rb │ │ ├── vault_keys.rb │ │ └── wait_for_network.rb │ ├── bash.rb │ ├── bash │ │ ├── __travis_go_functions.bash │ │ ├── travis_apt_get_options.bash │ │ ├── travis_apt_get_update.bash │ │ ├── travis_artifacts_install.bash │ │ ├── travis_assert.bash │ │ ├── travis_bash_qsort_numeric.bash │ │ ├── travis_cleanup.bash │ │ ├── travis_cmd.bash │ │ ├── travis_debug.bash │ │ ├── travis_decrypt.bash │ │ ├── travis_disable_ssh_roaming.bash │ │ ├── travis_disable_sudo.bash │ │ ├── travis_download.bash │ │ ├── travis_export_go.bash │ │ ├── travis_fake_sudo.bash │ │ ├── travis_find_jdk_path.bash │ │ ├── travis_fold.bash │ │ ├── travis_footer.bash │ │ ├── travis_getaddrinfo.bash │ │ ├── travis_ghc_find.bash │ │ ├── travis_ghc_install.bash │ │ ├── travis_ghc_setup_env.bash │ │ ├── travis_has_makefile.bash │ │ ├── travis_install_go_dependencies.bash │ │ ├── travis_install_jdk.bash │ │ ├── travis_internal_ruby.bash │ │ ├── travis_jigger.bash │ │ ├── travis_jinfo_file.bash │ │ ├── travis_key.bash │ │ ├── travis_maven_central_mirror.bash │ │ ├── travis_maven_https.bash │ │ ├── travis_munge_apt_sources.bash │ │ ├── travis_nanoseconds.bash │ │ ├── travis_preamble.bash │ │ ├── travis_prepare_go.bash │ │ ├── travis_remove_from_path.bash │ │ ├── travis_result.bash │ │ ├── travis_retry.bash │ │ ├── travis_script_go.bash │ │ ├── travis_setup_apt_proxy.bash │ │ ├── travis_setup_cri-dockerd.bash │ │ ├── travis_setup_env.bash │ │ ├── travis_setup_go.bash │ │ ├── travis_setup_java.bash │ │ ├── travis_setup_postgresql.bash │ │ ├── travis_start_sauce_connect.bash │ │ ├── travis_stop_sauce_connect.bash │ │ ├── travis_temporary_hacks.bash │ │ ├── travis_terminate.bash │ │ ├── travis_time_finish.bash │ │ ├── travis_time_start.bash │ │ ├── travis_trace_span.bash │ │ ├── travis_vers2int.bash │ │ ├── travis_wait.bash │ │ ├── travis_wait_for_network.bash │ │ └── travis_whereami.bash │ ├── config.rb │ ├── data.rb │ ├── data │ │ └── ssh_key.rb │ ├── env.rb │ ├── env │ │ ├── base.rb │ │ ├── builtin.rb │ │ ├── config.rb │ │ ├── settings.rb │ │ └── var.rb │ ├── errors.rb │ ├── helpers.rb │ ├── helpers │ │ ├── deprecation.rb │ │ └── template.rb │ ├── rake_tasks.rb │ ├── script.rb │ ├── script │ │ ├── android.rb │ │ ├── c.rb │ │ ├── clojure.rb │ │ ├── cpp.rb │ │ ├── crystal.rb │ │ ├── csharp.rb │ │ ├── d.rb │ │ ├── dart.rb │ │ ├── elixir.rb │ │ ├── elm.rb │ │ ├── erlang.rb │ │ ├── generic.rb │ │ ├── go.rb │ │ ├── groovy.rb │ │ ├── haskell.rb │ │ ├── haxe.rb │ │ ├── julia.rb │ │ ├── matlab.rb │ │ ├── nix.rb │ │ ├── node_js.rb │ │ ├── node_js │ │ │ ├── manager.rb │ │ │ └── manager │ │ │ │ ├── base.rb │ │ │ │ ├── nvm.rb │ │ │ │ └── nvs.rb │ │ ├── objective_c.rb │ │ ├── perl.rb │ │ ├── perl6.rb │ │ ├── php.rb │ │ ├── pure_java.rb │ │ ├── python.rb │ │ ├── r.rb │ │ ├── ruby.rb │ │ ├── rust.rb │ │ ├── scala.rb │ │ ├── shared │ │ │ ├── bundler.rb │ │ │ ├── chruby.rb │ │ │ ├── directory_cache.rb │ │ │ ├── directory_cache │ │ │ │ ├── base.rb │ │ │ │ ├── gcs.rb │ │ │ │ ├── noop.rb │ │ │ │ ├── s3.rb │ │ │ │ └── signatures │ │ │ │ │ ├── aws2_signature.rb │ │ │ │ │ └── aws4_signature.rb │ │ │ ├── jdk.rb │ │ │ ├── jvm.rb │ │ │ ├── rvm.rb │ │ │ └── workspace.rb │ │ └── smalltalk.rb │ ├── stages.rb │ └── stages │ │ ├── addon.rb │ │ ├── base.rb │ │ ├── builtin.rb │ │ ├── conditional.rb │ │ ├── custom.rb │ │ └── skip.rb │ ├── services │ ├── vault.rb │ └── vault │ │ ├── connect.rb │ │ ├── keys.rb │ │ └── keys │ │ ├── build_paths.rb │ │ ├── kv1.rb │ │ ├── kv2.rb │ │ ├── paths.rb │ │ ├── resolver.rb │ │ └── version.rb │ ├── shell.rb │ ├── shell │ ├── ast.rb │ ├── builder.rb │ ├── generator.rb │ └── generator │ │ ├── bash.rb │ │ └── bash │ │ ├── cmd.rb │ │ └── helpers.rb │ ├── support │ └── redis_pool.rb │ ├── vcs.rb │ └── vcs │ ├── base.rb │ ├── git.rb │ ├── git │ ├── clone.rb │ ├── netrc.rb │ ├── ssh_key.rb │ ├── submodules.rb │ └── tarball.rb │ ├── perforce.rb │ ├── perforce │ ├── clone.rb │ ├── netrc.rb │ ├── ssh_key.rb │ ├── submodules.rb │ └── tarball.rb │ ├── svn.rb │ └── svn │ ├── clone.rb │ ├── netrc.rb │ ├── ssh_key.rb │ ├── submodules.rb │ └── tarball.rb ├── public ├── empty.txt ├── filter.rb ├── filter │ ├── pty.rb │ └── redirect_io.rb └── version-aliases │ ├── README │ └── ghc.json ├── script ├── build-s3-index-html ├── compile ├── docker-build-and-push ├── get-latest-go ├── handle-docker-config ├── healthcheck ├── server └── validate-example-payloads-with-docker └── spec ├── api_spec.rb ├── build ├── addons │ ├── apt_packages_spec.rb │ ├── apt_retries_spec.rb │ ├── apt_spec.rb │ ├── artifacts │ │ ├── env_spec.rb │ │ └── validator_spec.rb │ ├── artifacts_spec.rb │ ├── blender_spec.rb │ ├── browserstack_spec.rb │ ├── chrome_spec.rb │ ├── code_climate_spec.rb │ ├── coverity_scan_spec.rb │ ├── deploy │ │ ├── conditions_spec.rb │ │ └── config_spec.rb │ ├── deploy_spec.rb │ ├── firefox_spec.rb │ ├── homebrew_spec.rb │ ├── hostname_spec.rb │ ├── hosts_spec.rb │ ├── jwt_spec.rb │ ├── mariadb_spec.rb │ ├── pkg_spec.rb │ ├── postgresql_spec.rb │ ├── rethinkdb_spec.rb │ ├── sauce_connect_spec.rb │ ├── snaps_spec.rb │ ├── sonarcloud_spec.rb │ ├── srcclr_spec.rb │ ├── ssh_known_hosts_spec.rb │ └── tensor_flow_spec.rb ├── addons_spec.rb ├── appliances │ ├── docker_config_spec.rb │ ├── vault_connect_spec.rb │ └── vault_keys_spec.rb ├── bash │ ├── travis_export_go_spec.rb │ ├── travis_getaddrinfo_spec.rb │ ├── travis_install_go_dependencies_spec.rb │ ├── travis_preamble_spec.rb │ ├── travis_prepare_go_spec.rb │ ├── travis_retry_spec.rb │ ├── travis_script_go_spec.rb │ ├── travis_setup_env_spec.rb │ ├── travis_setup_go_spec.rb │ ├── travis_temporary_hacks_spec.rb │ └── travis_whereami_spec.rb ├── config_spec.rb ├── data_spec.rb ├── env │ └── var_spec.rb ├── env_spec.rb ├── git │ ├── clone_spec.rb │ ├── ssh_key.rb │ ├── submodules_spec.rb │ └── tarball_spec.rb ├── git_spec.rb ├── rake_tasks_spec.rb ├── script │ ├── android_spec.rb │ ├── c_spec.rb │ ├── clojure_spec.rb │ ├── cpp_spec.rb │ ├── crystal_spec.rb │ ├── csharp_spec.rb │ ├── d_spec.rb │ ├── dart_spec.rb │ ├── directory_cache │ │ ├── gcs_spec.rb │ │ └── s3_spec.rb │ ├── directory_cache_spec.rb │ ├── elixir_spec.rb │ ├── elm_spec.rb │ ├── erlang_spec.rb │ ├── go_spec.rb │ ├── groovy_spec.rb │ ├── haskell_spec.rb │ ├── haxe_spec.rb │ ├── header_spec.rb │ ├── julia_spec.rb │ ├── matlab_spec.rb │ ├── nix_spec.rb │ ├── node_js_spec.rb │ ├── objective_c_spec.rb │ ├── perl6_spec.rb │ ├── perl_spec.rb │ ├── php_spec.rb │ ├── pure_java_spec.rb │ ├── python_spec.rb │ ├── r_spec.rb │ ├── ruby_spec.rb │ ├── rust_spec.rb │ ├── scala_spec.rb │ ├── shared │ │ ├── appliances │ │ │ ├── check_unsupported.rb │ │ │ ├── clean_up_path.rb │ │ │ ├── disable_initramfs.rb │ │ │ ├── disable_ssh_roaming.rb │ │ │ ├── disable_sudo.rb │ │ │ ├── disable_windows_defender.rb │ │ │ ├── env.rb │ │ │ ├── etc_hosts_pinning.rb │ │ │ ├── fix_etc_hosts.rb │ │ │ ├── fix_etc_mavenrc.rb │ │ │ ├── fix_mvn_settings_xml.rb │ │ │ ├── fix_ps4.rb │ │ │ ├── fix_resolv_conf.rb │ │ │ ├── fix_sudo_enabled_trusty.rb │ │ │ ├── no_ipv6_localhost.rb │ │ │ ├── npm_registry.rb │ │ │ ├── put_localhost_first.rb │ │ │ ├── rm_etc_boto_cfg.rb │ │ │ ├── rvm_use.rb │ │ │ ├── services.rb │ │ │ ├── setup_filter.rb │ │ │ ├── show_system_info.rb │ │ │ ├── stages.rb │ │ │ ├── uninstall_oclint.rb │ │ │ ├── update_apt_keys.rb │ │ │ ├── update_glibc.rb │ │ │ ├── update_libssl.rb │ │ │ └── validate.rb │ │ ├── bash_script.rb │ │ ├── jdk.rb │ │ ├── jvm.rb │ │ └── script.rb │ ├── smalltalk_spec.rb │ └── workspace_spec.rb ├── script_spec.rb ├── services │ └── vault │ │ ├── connect_spec.rb │ │ ├── keys │ │ ├── build_paths_spec.rb │ │ ├── kv1_spec.rb │ │ ├── kv2_spec.rb │ │ ├── paths_spec.rb │ │ ├── resolver_spec.rb │ │ └── version_spec.rb │ │ └── keys_spec.rb ├── vault_spec.rb ├── vcs │ ├── perforce │ │ └── clone_spec.rb │ ├── perforce_spec.rb │ └── svn │ │ ├── clone_spec.rb │ │ └── ssh_key_spec.rb └── vcs_spec.rb ├── build_spec.rb ├── filter_spec.rb ├── fixtures ├── build_config_with_vault_kv1.json └── build_config_with_vault_kv2.json ├── shell ├── ast_spec.rb └── generator │ ├── bash │ └── cmd_spec.rb │ └── bash_spec.rb ├── spec_helper.rb ├── spec_helpers ├── bash_function.rb ├── bash_script.rb ├── node.rb ├── payload.rb ├── sexp.rb └── shell.rb └── support ├── cache_slug_extras.rb ├── github_apps.rb ├── jwt_keys.rb ├── logger.rb ├── matchers ├── script.rb └── sexp.rb ├── payloads.rb └── ssh_key.rb /.dockerignore: -------------------------------------------------------------------------------- 1 | *.log 2 | /.bundle 3 | /.docker 4 | /.env 5 | /.rake_tasks 6 | /.rspec 7 | /.rubocop.yml 8 | /.rubocop_todo.yml 9 | /.simplecov 10 | /.travis.yml 11 | /.vagrant 12 | /CONTRIBUTING.md 13 | /Dockerfile 14 | /Procfile 15 | /README.md 16 | /coverage 17 | /docker-compose.yml 18 | /example_payloads 19 | /examples 20 | /init.rb 21 | /script/build-s3-index-html 22 | /script/docker-build-and-push 23 | /script/handle-docker-config 24 | /script/validate-example-payloads-with-docker 25 | /spec 26 | /tmp 27 | /vendor 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | *~ 3 | *# 4 | \#* 5 | bin/* 6 | .bundle/* 7 | /tmp/ 8 | play/*.sh 9 | examples/ 10 | rspec.log 11 | .vagrant 12 | coverage/ 13 | .*env 14 | /public/files/ 15 | .rake_tasks 16 | /.docker/ 17 | vendor/ 18 | /.idea/ 19 | .history 20 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --order rand 3 | --require pry 4 | --require spec_helper 5 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: .rubocop_todo.yml 2 | 3 | AllCops: 4 | TargetRubyVersion: 2.5 5 | Include: 6 | - '**/Gemfile' 7 | - '**/Rakefile' 8 | - '**/config.ru' 9 | - '**/lib/core_ext/**/*.rb' 10 | - '**/lib/travis/build/rake_tasks.rb' 11 | - '**/script/{build-s3-index-html,compile}' 12 | Exclude: 13 | - 'tmp/**/*' 14 | - 'public/files/**/*' 15 | 16 | Metrics/AbcSize: 17 | Max: 50 18 | 19 | Metrics/MethodLength: 20 | Max: 50 21 | 22 | Metrics/ModuleLength: 23 | Max: 500 24 | 25 | Style/ModuleFunction: 26 | Exclude: 27 | - '**/lib/travis/build/rake_tasks.rb' 28 | 29 | Style/Documentation: 30 | Enabled: false 31 | 32 | Style/MixinUsage: 33 | Exclude: 34 | - Rakefile 35 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2019-01-10 09:32:50 -0500 using RuboCop version 0.59.2. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | travis-build 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.2 2 | -------------------------------------------------------------------------------- /.simplecov: -------------------------------------------------------------------------------- 1 | # vim:filetype=ruby 2 | SimpleCov.start do 3 | add_filter '/spec/' 4 | add_filter '/script/' 5 | add_filter '/examples/' 6 | add_filter '/play/' 7 | add_filter '/tmp/' 8 | end if ENV['COVERAGE'] 9 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Travis-CI 2 | Issues for any Travis-CI repo should be raised to the https://travis-ci.community/ forum 3 | 4 | ## Security Issues 5 | ***Any security issues should be submitted directly to [security@travis-ci.org](mailto:security@travis-ci.org)*** 6 | 7 | ## Reporting Issues 8 | - Explain what you expected to happen vs the actual results 9 | - Include a screenshot if it helps illustrate the issue. https://github.com/blog/1347-issue-attachments 10 | - What steps are required to reproduce the issue 11 | - An example build that shows the issue 12 | 13 | ## Submitting a PR to Travis-Build 14 | 15 | See testing and setup notes in the base [README](https://github.com/travis-ci/travis-build) 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2.2 as builder 2 | 3 | ARG GITHUB_OAUTH_TOKEN=notset 4 | 5 | RUN gem update --system 3.3.26 > /dev/null 2>&1 6 | 7 | WORKDIR /app 8 | 9 | COPY . . 10 | 11 | RUN git describe --always --dirty --tags | tee VERSION 12 | RUN git rev-parse --short HEAD | tee BUILD_SLUG_COMMIT 13 | RUN rm -rf .git 14 | 15 | RUN bundle install --frozen --deployment --without='development test' --clean 16 | 17 | RUN bundle exec rake assets:precompile GITHUB_OAUTH_TOKEN=$GITHUB_OAUTH_TOKEN 18 | RUN tar -cjf public.tar.bz2 public && rm -rf public 19 | 20 | 21 | FROM ruby:3.2.2-slim 22 | 23 | LABEL maintainer Travis CI GmbH 24 | 25 | ENV TRAVIS_BUILD_DUMP_BACKTRACE true 26 | ENV PORT 4000 27 | 28 | RUN gem update --system 3.3.26 > /dev/null 2>&1 29 | RUN ( \ 30 | apt-get update ; \ 31 | apt-get install -y --no-install-recommends libjemalloc-dev\ 32 | && rm -rf /var/lib/apt/lists/* \ 33 | ) 34 | 35 | WORKDIR /app 36 | 37 | COPY --from=builder /app /app 38 | COPY --from=builder /usr/local/bundle/config /usr/local/bundle/config 39 | RUN cp /app/script/get-latest-go /etc/cron.daily/ 40 | 41 | HEALTHCHECK --interval=5s CMD script/healthcheck 42 | 43 | EXPOSE $PORT/tcp 44 | 45 | CMD ["script/server"] 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2018 Travis CI GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: script/server 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | begin 4 | require 'parallel_tests/tasks' 5 | require 'rspec/core/rake_task' 6 | require 'rubocop/rake_task' 7 | 8 | RSpec::Core::RakeTask.new(:spec) 9 | RuboCop::RakeTask.new 10 | rescue LoadError => e 11 | warn e 12 | end 13 | 14 | $LOAD_PATH.unshift(File.expand_path('lib', __dir__)) 15 | require 'travis/build/rake_tasks' 16 | include Travis::Build::RakeTasks 17 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'travis/api/build/app' 4 | 5 | run Travis::Api::Build::App 6 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | web: 3 | build: 4 | context: . 5 | args: 6 | - GITHUB_OAUTH_TOKEN 7 | environment: 8 | - RACK_ENV=${RACK_ENV:-production} 9 | ports: 10 | - 4000:4000 11 | -------------------------------------------------------------------------------- /example_payloads/skip.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "script": "skip" 4 | }, 5 | "repository": { 6 | "slug": "travis-repos/chirp-org-staging", 7 | "source_url": "https://github.com/travis-repos/chirp-org-staging.git" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /je: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Help 3 | def usage 4 | puts < Injecting jemalloc..." if $verbose 33 | ENV.store("LD_PRELOAD", lib_dir + "/jemalloc.so") 34 | elsif File.exist? (lib_dir + "/jemalloc.bundle") 35 | puts "=> Injecting jemalloc..." if $verbose 36 | ENV.store("DYLD_INSERT_LIBRARIES", lib_dir + "/jemalloc.bundle") 37 | elsif File.exist? ($sys_jemalloc) 38 | puts "=> Injecting jemalloc..." if $verbose 39 | ENV.store("LD_PRELOAD", $sys_jemalloc) 40 | else 41 | puts "=> Can't inject, jemalloc not found" 42 | end 43 | 44 | Kernel.exec *argv 45 | -------------------------------------------------------------------------------- /lib/core_ext/hash/compact.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Hash 4 | def compact 5 | each_with_object({}) do |(key, value), result| 6 | result[key] = value unless value.nil? 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/core_ext/hash/deep_merge.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Hash 4 | # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809 5 | DEEP_MERGER = proc do |_key, v1, v2| 6 | v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2, &DEEP_MERGER) : v2 7 | end 8 | 9 | unless Hash.method_defined?(:deep_merge) 10 | def deep_merge(data) 11 | merge(data, &DEEP_MERGER) 12 | end 13 | end 14 | 15 | unless Hash.method_defined?(:deep_merge!) 16 | def deep_merge!(data) 17 | merge!(data, &DEEP_MERGER) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/core_ext/hash/deep_symbolize_keys.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Hash 4 | unless Hash.method_defined?(:deep_symbolize_keys) 5 | def deep_symbolize_keys 6 | each_with_object({}) do |(key, value), result| 7 | key = deep_symbolize_key(key) || key 8 | result[key] = deep_symbolize_coerce_value(value) 9 | end 10 | end 11 | 12 | def deep_symbolize_key(key) 13 | key.to_sym 14 | rescue StandardError 15 | key 16 | end 17 | 18 | private :deep_symbolize_key 19 | 20 | def deep_symbolize_coerce_value(value) 21 | case value 22 | when Array 23 | value.map { |v| v.is_a?(Hash) ? v.deep_symbolize_keys : v } 24 | when Hash 25 | value.deep_symbolize_keys 26 | else 27 | value 28 | end 29 | end 30 | 31 | private :deep_symbolize_coerce_value 32 | end 33 | 34 | unless Hash.method_defined?(:deep_symbolize_keys!) 35 | def deep_symbolize_keys! 36 | replace(deep_symbolize_keys) 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/core_ext/object/false.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Object 4 | def false? 5 | is_a?(FalseClass) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/core_ext/string/indent.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class String 4 | def indent(level) 5 | split("\n").map { |line| ' ' * (level * 2) + line }.join("\n") 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/core_ext/string/output_safe.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class String 4 | def output_safe 5 | dup 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/core_ext/string/to_bool.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class String 4 | def to_bool 5 | %w[true yes 1 on].include?(downcase) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/core_ext/string/unindent.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class String 4 | def unindent 5 | gsub(/^#{self[/\A\s*/]}/, '') 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/travis.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | autoload :Build, 'travis/build' 3 | 4 | def config 5 | ::Travis::Build.config 6 | end 7 | 8 | module_function :config 9 | end 10 | -------------------------------------------------------------------------------- /lib/travis/api/build/sentry.rb: -------------------------------------------------------------------------------- 1 | require 'raven' 2 | require 'raven/integrations/rack' 3 | require 'sinatra/base' 4 | 5 | module Travis 6 | module Api 7 | module Build 8 | class Sentry < Sinatra::Base 9 | configure do 10 | Raven.configure do |config| 11 | config.tags = { environment: environment } 12 | end 13 | use Raven::Rack 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/travis/build/.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | -------------------------------------------------------------------------------- /lib/travis/build/addons/apt_packages.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/addons/apt' 2 | 3 | module Travis 4 | module Build 5 | class Addons 6 | class AptPackages 7 | SUPER_USER_SAFE = true 8 | 9 | class << self 10 | def new(script, sh, data, config) 11 | ::Travis::Build::Addons::Apt.new(script, sh, data, { packages: config }) 12 | end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/addons/apt_retries.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/addons/base' 2 | 3 | module Travis 4 | module Build 5 | class Addons 6 | class AptRetries < Base 7 | SUPER_USER_SAFE = true 8 | 9 | def before_configure? 10 | config 11 | end 12 | 13 | def before_configure 14 | sh.echo "Configuring default apt-get retries", ansi: :yellow 15 | sh.raw <<~EOF 16 | if [[ -d /var/lib/apt/lists && -n $(command -v apt-get) ]]; then 17 | cat <<-EOS > 99-travis-build-retries 18 | Acquire { 19 | ForceIPv4 "1"; 20 | Retries "5"; 21 | https { 22 | Timeout "30"; 23 | }; 24 | }; 25 | EOS 26 | sudo mv 99-travis-build-retries /etc/apt/apt.conf.d 27 | fi 28 | EOF 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/travis/build/addons/base.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | require 'travis/build/helpers/template' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class Base 8 | attr_reader :script, :sh, :data, :config 9 | 10 | extend Forwardable 11 | def_delegators :script, :bash 12 | 13 | def initialize(script, sh, data, config) 14 | @script = script 15 | @sh = sh 16 | @data = data 17 | @config = normalize_config(config) 18 | end 19 | 20 | def normalize_config(config) 21 | case config 22 | when Integer, Float, String, Array, Hash 23 | config 24 | else 25 | {} 26 | end 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/travis/build/addons/blender.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | require 'travis/build/addons/base' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class Blender < Base 8 | ALLOWED_VERSIONS = %w[3.4.1].freeze 9 | 10 | def after_prepare 11 | sh.fold 'blender' do 12 | if data.config[:os] != 'linux' 13 | sh.echo 'Blender is only available for linux', ansi: :red 14 | return 15 | end 16 | 17 | if version.nil? 18 | sh.echo "Blender: Invalid version '#{raw_version}' given. Valid versions are: #{ALLOWED_VERSIONS.join(', ')}", 19 | ansi: :red 20 | return 21 | end 22 | sh.echo "Installing Blender version: #{version}", ansi: :yellow 23 | sh.cmd 'CURL_USER_AGENT="Travis-CI $(curl --version | head -n 1)"', echo: true 24 | sh.cmd 'mkdir ${TRAVIS_HOME}/blender', echo: true 25 | sh.cmd "curl -A \"$CURL_USER_AGENT\" -sSf -L --retry 7 https://ftp.halifax.rwth-aachen.de/blender/release/Blender#{version[/\d+\.\d+/]}/blender-#{version}-linux-x64.tar.xz" \ 26 | ' | tar xf - -J -C ${TRAVIS_HOME}/blender --strip-components 1', echo: true 27 | sh.cmd 'PATH=$PATH:${TRAVIS_HOME}/blender', echo: true 28 | end 29 | end 30 | 31 | private 32 | 33 | def raw_version 34 | config.to_s.strip.shellescape 35 | end 36 | 37 | def version 38 | ALLOWED_VERSIONS.include?(raw_version) ? raw_version : nil 39 | end 40 | end 41 | end 42 | end 43 | end -------------------------------------------------------------------------------- /lib/travis/build/addons/code_climate.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/addons/base' 2 | 3 | module Travis 4 | module Build 5 | class Addons 6 | class CodeClimate < Base 7 | SUPER_USER_SAFE = true 8 | 9 | def before_before_script 10 | sh.export 'CODECLIMATE_REPO_TOKEN', token, echo: false if token 11 | end 12 | 13 | private 14 | 15 | def token 16 | config[:repo_token] 17 | rescue 18 | false 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/travis/build/addons/deploy.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/addons/base' 2 | require 'travis/build/addons/deploy/script' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class Deploy < Base 8 | SUPER_USER_SAFE = true 9 | 10 | def initialize(script, sh, data, config) 11 | super(script, sh, data, config.is_a?(Array) ? config : [config].compact) 12 | end 13 | 14 | def after_after_success? 15 | !config.empty? 16 | end 17 | 18 | def after_after_success 19 | # sh.if('$TRAVIS_TEST_RESULT = 0') do 20 | # providers.map(&:deploy) 21 | # end 22 | last_deploy = nil 23 | config.each_with_index do |config, id| 24 | provider = Script.new(script, sh, data, config, id, last_deploy) 25 | provider.deploy 26 | last_deploy = config 27 | end 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/travis/build/addons/hostname.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Build 3 | class Addons 4 | class Hostname < Base 5 | def after_prepare 6 | sh.echo "Set hostname to #{hostname}", ansi: :yellow 7 | sh.cmd "sudo hostname #{hostname}", echo: true 8 | end 9 | 10 | def hostname 11 | config.to_s.shellescape 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/travis/build/addons/hosts.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | require 'travis/build/addons/base' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class Hosts < Base 8 | SUPER_USER_SAFE = true 9 | HOSTS_FILE = '/etc/hosts' 10 | TEMP_HOSTS_FILE = '/tmp/hosts' 11 | 12 | def after_prepare 13 | sh.fold 'hosts.before' do 14 | sh.newline 15 | sh.cmd "cat #{HOSTS_FILE}" 16 | sh.newline 17 | end 18 | sh.fold 'hosts' do 19 | sh.cmd "sed -e 's/^\\(127\\.0\\.0\\.1.*\\)$/\\1 #{hosts}/' #{HOSTS_FILE} > #{TEMP_HOSTS_FILE}" 20 | sh.cmd "cat #{TEMP_HOSTS_FILE} | sudo tee #{HOSTS_FILE} > /dev/null" 21 | end 22 | sh.fold 'hosts.after' do 23 | sh.newline 24 | sh.cmd "cat #{HOSTS_FILE}" 25 | sh.newline 26 | end 27 | end 28 | 29 | private 30 | 31 | def hosts 32 | Array(config).join(' ').shellescape 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/travis/build/addons/jwt.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/addons/base' 2 | require 'jwt' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class Jwt < Base 8 | SUPER_USER_SAFE = true 9 | 10 | def before_before_install 11 | sh.echo "JWT addon will be deprecated on April 17, 2018. Please read our announcement at https://blog.travis-ci.com/2018-01-23-jwt-addon-is-deprecated", ansi: :red 12 | 13 | tokens = {} 14 | Array(config).each do |secret| 15 | pull_request = self.data.pull_request ? self.data.pull_request : "" 16 | now = Time.now.to_i() 17 | payload = { 18 | "iss" => "Travis CI, GmbH", 19 | "slug" => self.data.slug, 20 | "pull-request" => pull_request, 21 | "exp" => now+5400, 22 | "iat" => now 23 | } 24 | begin 25 | key, secret = secret.split('=').map(&:strip) 26 | tokens[key] = JWT.encode(payload, secret) 27 | rescue Exception 28 | sh.echo "There was an error while encoding JWT. If the secret is encrypted, ensure that it is encrypted correctly.", ansi: :yellow 29 | end 30 | end 31 | return if tokens.empty? 32 | sh.fold 'addons_jwt' do 33 | sh.echo 'Initializing JWT', ansi: :yellow 34 | tokens.each do |key, val| 35 | sh.export key, val, echo: false 36 | end 37 | end 38 | end 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/travis/build/addons/postgresql.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | require 'travis/build/addons/base' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class Postgresql < Base 8 | SUPER_USER_SAFE = true 9 | 10 | def after_prepare 11 | sh.if '"$TRAVIS_OS_NAME" != linux' do 12 | sh.echo "Addon PostgreSQL is not supported on #{data[:config][:os]}", ansi: :red 13 | end 14 | sh.else do 15 | sh.fold 'postgresql' do 16 | sh.raw bash('travis_setup_postgresql'), echo: false, timing: false 17 | sh.cmd "travis_setup_postgresql #{version}", echo: true, timing: true 18 | end 19 | end 20 | end 21 | 22 | private 23 | 24 | def version 25 | config.to_s.shellescape 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/travis/build/addons/sbom.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/addons/base' 2 | require 'travis/build/addons/sbom/script' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class Sbom < Base 8 | SUPER_USER_SAFE = true 9 | 10 | def before_script? 11 | !config.empty? && config[:run_phase] == 'before_script' 12 | end 13 | 14 | def script? 15 | !config.empty? && config[:run_phase] == 'script' 16 | end 17 | 18 | def after_after_success? 19 | !config.empty? && config[:run_phase] == 'after_success' 20 | end 21 | 22 | def after_after_failure? 23 | !config.empty? && config[:run_phase] == 'after_failure' 24 | end 25 | 26 | def before_script 27 | Script.new(@script, sh, data, config).generate 28 | end 29 | 30 | def script 31 | Script.new(@script, sh, data, config).generate 32 | end 33 | 34 | def after_after_success 35 | sh.if('$TRAVIS_TEST_RESULT = 0') do 36 | Script.new(@script, sh, data, config).generate 37 | end 38 | end 39 | 40 | def after_after_failure 41 | sh.if('$TRAVIS_TEST_RESULT != 0') do 42 | Script.new(@script, sh, data, config).generate 43 | end 44 | end 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/travis/build/addons/sonarqube.rb: -------------------------------------------------------------------------------- 1 | require 'digest/md5' 2 | require 'shellwords' 3 | require 'travis/build/addons/base' 4 | require 'travis/build/addons/sonarcloud' 5 | 6 | module Travis 7 | module Build 8 | class Addons 9 | class Sonarqube < Sonarcloud 10 | def after_install 11 | sh.echo "sonarqube addon has been renamed to sonarcloud. Please update your configuration.", echo: false, ansi: :yellow 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/travis/build/addons/srcclr.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | require 'travis/build/addons/base' 4 | 5 | module Travis 6 | module Build 7 | class Addons 8 | class Srcclr < Base 9 | SUPER_USER_SAFE = true 10 | 11 | def before_finish 12 | sh.if('$TRAVIS_TEST_RESULT = 0') do 13 | sh.newline 14 | sh.fold 'srcclr' do 15 | sh.if "-z $SRCCLR_API_TOKEN" do 16 | sh.echo "SRCCLR_API_TOKEN is empty", ansi: :red 17 | end 18 | 19 | sh.echo "Running SourceClear agent", ansi: :yellow 20 | debug_env = debug? ? "env DEBUG=1" : "" 21 | 22 | sh.cmd "curl -sSL https://download.sourceclear.com/ci.sh | #{debug_env} bash", echo: true, timing: true 23 | end 24 | end 25 | end 26 | 27 | def debug? 28 | config[:debug] 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/travis/build/addons/tensor_flow.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | require 'travis/build/addons/base' 3 | 4 | module Travis 5 | module Build 6 | class Addons 7 | class TensorFlow < Base 8 | ALLOWED_VERSIONS = %w[0.12.1 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 9 | 1.6.0 1.7.0 1.7.1 1.8.0 1.9.0 1.10.0 1.10.1 1.11.0 1.12.0 1.12.2 1.12.3 10 | 1.13.1 1.13.2 1.14.0 1.15.0 1.15.2 1.15.31.15.4 1.15.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1.0 2.1.1 2.1.2 2.1.3 11 | 2.1.4 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.5.2 12 | 2.6.0rc0 2.6.0rc1 2.6.0rc2 2.6.0 2.6.1 2.6.2].freeze 13 | 14 | def after_prepare 15 | sh.fold 'tensor_flow' do 16 | if version.nil? 17 | sh.echo "Invalid version '#{raw_version}' given. Valid versions are: #{ALLOWED_VERSIONS.join(' ')}", ansi: :red 18 | return 19 | end 20 | sh.echo "Installing TensorFlow version: #{version}", ansi: :yellow 21 | sh.cmd "pip install tensorflow==#{version}", sudo: false 22 | end 23 | end 24 | 25 | private 26 | 27 | def raw_version 28 | config.to_s.strip.shellescape 29 | end 30 | 31 | def version 32 | ALLOWED_VERSIONS.include?(raw_version) ? raw_version : nil 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/agent/jwt.rb: -------------------------------------------------------------------------------- 1 | require 'jwt' 2 | require 'openssl' 3 | require 'securerandom' 4 | 5 | module Jwt 6 | class RefreshToken < Struct.new(:key, :job_id, :site) 7 | MAX_DURATION = 600 8 | ALG = 'RS512' 9 | 10 | def create 11 | ::JWT.encode(payload, key, ALG) 12 | end 13 | 14 | def rand 15 | @rand ||= SecureRandom.hex 16 | end 17 | 18 | private 19 | 20 | def payload 21 | { 22 | iss: 'build', 23 | typ: 'refresh', 24 | sub: job_id, 25 | exp: expires.to_i, 26 | site: site, 27 | rand: rand 28 | } 29 | end 30 | 31 | def expires 32 | Time.now.utc + MAX_DURATION 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/base.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class Base < Struct.new(:script) 7 | extend Forwardable 8 | 9 | def_delegators :script, :sh, :data, :config, :app_host, :bash 10 | 11 | def apply? 12 | not windows? 13 | end 14 | 15 | def windows? 16 | config[:os] == 'windows' 17 | end 18 | 19 | def linux? 20 | config[:os] == 'linux' 21 | end 22 | 23 | def time? 24 | true 25 | end 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/check_unsupported.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class CheckUnsupported < Base 7 | def apply 8 | lang_name = config[:language] 9 | unless windows_supports?(lang_name) 10 | sh.if '"$TRAVIS_OS_NAME" = windows' do 11 | windows_unsupported_msg(lang_name).each do |line| 12 | sh.echo line, ansi: :yellow 13 | end 14 | sh.raw 'travis_terminate 1' 15 | end 16 | end 17 | end 18 | 19 | def apply? 20 | true 21 | end 22 | 23 | private 24 | 25 | def windows_supports?(lang) 26 | Travis::Build.config.windows_langs.include?(lang) 27 | end 28 | 29 | def windows_unsupported_msg(lang) 30 | [ 31 | "", 32 | "The language '#{lang}' is currently unsupported on the Windows Build Environment.", 33 | "", 34 | "Let us know if you'd like to see it: https://travis-ci.community/c/environments/windows. Thanks for understanding!", 35 | ] 36 | end 37 | 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/checkout.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | require 'travis/vcs' 3 | 4 | module Travis 5 | module Build 6 | module Appliances 7 | class Checkout < Base 8 | def apply 9 | Travis::Vcs.checkout(sh, data) 10 | end 11 | 12 | def apply? 13 | true 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/clean_up_path.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class CleanUpPath < Base 7 | def apply 8 | sh.export 'PATH', "$(echo $PATH | sed -e 's/::/:/g')", echo: false 9 | sh.export 'PATH', "$(echo -n $PATH | perl -e 'print join(\":\", grep { not $seen{$_}++ } split(/:/, scalar <>))')", echo: false 10 | end 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/debug_tools/templates/tmate.conf.erb: -------------------------------------------------------------------------------- 1 | set -g tmate-identity "<%= identity %>" 2 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/deprecate_xcode_64.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class DeprecateXcode64 < Base 7 | def apply 8 | if config[:osx_image] == 'xcode6.4' 9 | sh.newline 10 | sh.echo "Running builds with Xcode 6.4 in Travis CI is deprecated and will be removed in January 2019.", ansi: :yellow 11 | sh.echo "If Xcode 6.4 is critical to your builds, please contact our support team at support@travis-ci.com to discuss options.", ansi: :yellow 12 | end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/deprecations.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class Deprecations < Base 7 | def apply 8 | # script.deprecations.map.with_index do |msg, ix| 9 | # sh.fold "deprecated.#{ix}", pos: ix do 10 | # sh.deprecate "DEPRECATED: #{msg.gsub /^#{msg[/\A\s*/]}/, ''}" 11 | # end 12 | # end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/disable_initramfs.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class DisableInitramfs < Base 7 | def apply 8 | sh.raw "if [ ! $(uname|egrep 'Darwin|FreeBSD') ]; then echo update_initramfs=no | sudo tee -a /etc/initramfs-tools/update-initramfs.conf > /dev/null; fi" 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/disable_ssh_roaming.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class DisableSshRoaming < Base 7 | def apply 8 | sh.raw bash('travis_disable_ssh_roaming') 9 | sh.if %("$(sw_vers -productVersion 2>/dev/null | cut -d . -f 2)" -lt 12) do 10 | sh.cmd 'travis_disable_ssh_roaming' 11 | end 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/disable_sudo.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class DisableSudo < Base 7 | def apply 8 | sh.file "${TRAVIS_TMPDIR}/fake-sudo", bash('travis_fake_sudo') 9 | sh.raw bash('travis_disable_sudo') 10 | sh.cmd 'travis_disable_sudo' 11 | end 12 | 13 | def apply? 14 | super && data.disable_sudo? 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/disable_windows_defender.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class DisableWindowsDefender< Base 7 | def apply 8 | sh.echo "Disabling Windows Defender", ansi: :yellow 9 | sh.cmd 'powershell -Command Set-MpPreference -DisableArchiveScanning \\$true', echo: true 10 | sh.cmd 'powershell -Command Set-MpPreference -DisableRealtimeMonitoring \\$true', echo: true 11 | sh.cmd 'powershell -Command Set-MpPreference -DisableBehaviorMonitoring \\$true', echo: true 12 | end 13 | 14 | def apply? 15 | windows? 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/docker_config.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | require 'travis/build/appliances/base' 3 | require 'travis/build/helpers/template' 4 | 5 | module Travis 6 | module Build 7 | module Appliances 8 | class DockerConfig < Base 9 | include Template 10 | 11 | def apply 12 | sh.fold "Docker config" do 13 | sh.raw "export BUILDKIT_PROGRESS=#{buildkit_progress}" 14 | end 15 | end 16 | 17 | def buildkit_progress 18 | ENV['TRAVIS_BUILD_DOCKER_BUILDKIT_PROGRESS'] || 'plain' 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/enable_i386.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class EnableI386 < Base 7 | def apply 8 | sh.if "$(uname -m) == x86_64 && $(command -v lsb_release) && $(lsb_release -cs) != precise" do 9 | sh.cmd 'dpkg --add-architecture i386', echo: false, assert: false, sudo: true 10 | end 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/ensure_path_components.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class EnsurePathComponents < Base 7 | 8 | COMPONENTS = [ 9 | '$(yarn global bin 2>/dev/null | grep /)' 10 | ] 11 | 12 | def apply 13 | COMPONENTS.each do |pc| 14 | sh.cmd <<~EOF 15 | [[ -n "#{pc}" && ! :$PATH: =~ :#{pc}: ]] && export PATH="$PATH:#{pc}" 16 | EOF 17 | end 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/env.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class Env < Base 7 | MSG = "Setting environment variables from %s" 8 | 9 | def apply 10 | if data.secure_env_removed? 11 | sh.newline 12 | sh.echo "Encrypted environment variables have been removed for security reasons.", ansi: :yellow 13 | sh.echo "See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions", ansi: :yellow 14 | end 15 | 16 | env.groups.each { |group| export(group) } 17 | sh.newline if env.announce? 18 | end 19 | 20 | def apply? 21 | true 22 | end 23 | 24 | private 25 | 26 | def export(group) 27 | announce(group) if group.announce? 28 | group.vars.each do |var| 29 | sh.export(var.key, var.value, echo: var.echo?, secure: var.secure?) 30 | end 31 | end 32 | 33 | def announce(group) 34 | sh.newline 35 | sh.echo MSG % group.source, ansi: :yellow 36 | end 37 | 38 | def env 39 | @env ||= Build::Env.new(data) 40 | end 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/etc_hosts_pinning.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | require 'travis/build/appliances/base' 3 | 4 | module Travis 5 | module Build 6 | module Appliances 7 | class EtcHostsPinning < Base 8 | def apply 9 | Travis::Build.config.etc_hosts_pinning.to_s.output_safe.split(',').each do |etchostsline| 10 | sh.raw %(echo #{Shellwords.escape(etchostsline)} | sudo tee -a /etc/hosts &>/dev/null) 11 | end 12 | end 13 | 14 | def apply? 15 | super && !Travis::Build.config.etc_hosts_pinning.to_s.strip.empty? 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_container_based_trusty.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'travis/build/appliances/base' 4 | 5 | module Travis 6 | module Build 7 | module Appliances 8 | class FixContainerBasedTrusty < Base 9 | def apply 10 | sh.if sh_is_linux? do 11 | sh.if sh_is_trusty? do 12 | # NOTE: no fixes currently needed :tada: 13 | end 14 | end 15 | end 16 | 17 | def apply? 18 | false 19 | end 20 | 21 | private 22 | 23 | def sh_is_linux? 24 | '$(uname) = Linux' 25 | end 26 | 27 | def sh_is_trusty? 28 | '$(lsb_release -sc 2>/dev/null) = trusty' 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_etc_hosts.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixEtcHosts < Base 7 | def apply 8 | sh.raw %(sudo sed -e 's/^\\(127\\.0\\.0\\.1.*\\)$/\\1 '`hostname`'/' -i'.bak' /etc/hosts 2> /dev/null) 9 | end 10 | 11 | def apply? 12 | return unless super 13 | if data.key?(:fix_etc_hosts) 14 | data[:fix_etc_hosts] 15 | else 16 | !data[:skip_etc_hosts_fix] 17 | end 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_etc_mavenrc.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixEtcMavenrc < Base 7 | def apply 8 | sh.raw %(test -f /etc/mavenrc && sudo sed -e 's/M2_HOME=\\(.\\+\\)$/M2_HOME=${M2_HOME:-\\1}/' -i'.bak' /etc/mavenrc) 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_hhvm_source.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixHhvmSource < Base 7 | def apply 8 | command = <<-EOF 9 | if command -v lsb_release; then 10 | grep -l -i -r hhvm /etc/apt/sources.list.d | xargs sudo rm -f 11 | sudo sed -i /hhvm/d /etc/apt/sources.list 12 | if [[ $(lsb_release -cs) = trusty ]]; then 13 | sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xB4112585D386EB94 14 | sudo add-apt-repository "deb [arch=amd64] http://dl.hhvm.com/ubuntu $(lsb_release -sc) main" 15 | fi 16 | fi &>/dev/null 17 | EOF 18 | sh.cmd command, assert: false 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_mvn_settings_xml.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixMvnSettingsXml < Base 7 | def apply 8 | sh.if "-f ~/.m2/settings.xml" do 9 | sh.cmd %(sed -i$([ "$TRAVIS_OS_NAME" == osx ] && echo " ").bak1 -e 's|https://nexus.codehaus.org/snapshots/|https://oss.sonatype.org/content/repositories/codehaus-snapshots/|g' ~/.m2/settings.xml), echo: false, assert: false, timing: false 10 | sh.cmd %(sed -i$([ "$TRAVIS_OS_NAME" == osx ] && echo " ").bak2 -e 's|https://repository.apache.org/releases/|https://repository.apache.org/content/repositories/releases/|g' ~/.m2/settings.xml), echo: false, assert: false, timing: false 11 | end 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_perforce_key.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixPerforceKey < Base 7 | def apply 8 | sh.if "! $(command -v sw_vers)" do 9 | sh.cmd "wget -qO - https://package.perforce.com/perforce.pubkey | sudo apt-key add -", assert: false, echo: false 10 | end 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_ps4.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixPs4 < Base 7 | def apply 8 | sh.export 'PS4', '+', echo: false 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_resolv_conf.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixResolvConf < Base 7 | def apply 8 | current_resolv_conf = File.read('/etc/resolv.conf') 9 | resolv_conf_data = <<-EOF 10 | options rotate 11 | options timeout:1 12 | 13 | nameserver 8.8.8.8 14 | nameserver 8.8.4.4 15 | nameserver 208.67.222.222 16 | nameserver 208.67.220.220 17 | EOF 18 | 19 | if current_resolv_conf =~ /nameserver\s+199\.91\.168/ 20 | resolv_conf_data << "\nnameserver 199.91.168.70\nnameserver 199.91.168.71\n" 21 | end 22 | sh.raw %(echo "#{resolv_conf_data}" | sudo tee /etc/resolv.conf &> /dev/null) 23 | end 24 | 25 | def apply? 26 | return unless super 27 | if data.key?(:fix_resolv_conf) 28 | data[:fix_resolv_conf] 29 | else 30 | !data[:skip_resolv_updates] 31 | end 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_rwky_redis.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixRwkyRedis < Base 7 | def apply 8 | command = <<-EOF 9 | if [[ -d /var/lib/apt/lists && -n $(command -v apt-get) ]]; then 10 | for f in $(grep -l -r rwky/redis /etc/apt/sources.list.d); do 11 | sed 's,rwky/redis,rwky/ppa,g' $f > /tmp/${f##**/} 12 | sudo mv /tmp/${f##**/} /etc/apt/sources.list.d 13 | done 14 | fi 15 | EOF 16 | sh.cmd command, echo: false 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_sudo_enabled_trusty.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'travis/build/appliances/base' 4 | 5 | module Travis 6 | module Build 7 | module Appliances 8 | class FixSudoEnabledTrusty < Base 9 | def apply 10 | sh.if sh_is_linux? do 11 | sh.if sh_is_trusty? do 12 | sh.cmd 'unset _JAVA_OPTIONS', echo: false 13 | sh.cmd 'unset MALLOC_ARENA_MAX', echo: false 14 | end 15 | end 16 | end 17 | 18 | def apply? 19 | super && !data.disable_sudo? 20 | end 21 | 22 | private 23 | 24 | def sh_is_linux? 25 | '$(uname) = Linux' 26 | end 27 | 28 | def sh_is_trusty? 29 | '$(lsb_release -sc 2>/dev/null) = trusty' 30 | end 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/fix_wwdr_certificate.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class FixWwdrCertificate < Base 7 | def apply 8 | sh.if "$(command -v sw_vers)" do 9 | sh.cmd "sudo security delete-certificate -Z 0950B6CD3D2F37EA246A1AAA20DFAADBD6FE1F75 /Library/Keychains/System.keychain &>/dev/null", assert: false, echo: false 10 | sh.cmd "wget -q https://developer.apple.com/certificationauthority/AppleWWDRCA.cer", assert: false, echo: false 11 | sh.cmd "sudo security add-certificates -k /Library/Keychains/System.keychain AppleWWDRCA.cer &>/dev/null", assert: false, echo: false 12 | end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/git_v2.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class GitV2 < Base 7 | def apply 8 | sh.cmd "git config --global protocol.version 2" 9 | end 10 | 11 | def apply? 12 | config[:os] == 'osx' && config[:osx_image] && config[:osx_image] == 'xcode10.2' 13 | end 14 | end 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /lib/travis/build/appliances/home_paths.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class HomePaths < Base 7 | def apply 8 | # XXX Ensure $PATH is prepended with a few entries to ease development in 9 | # container-based infrastructure. 10 | sh.cmd <<~BASH 11 | # apply :home_paths 12 | for path_entry in ${TRAVIS_HOME}/.local/bin ${TRAVIS_HOME}/bin ; do 13 | if [[ ${PATH%%:*} != ${path_entry} ]] ; then 14 | export PATH="${path_entry}:$PATH" 15 | fi 16 | done 17 | BASH 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/maven_central_mirror.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | module Travis 3 | module Build 4 | module Appliances 5 | class MavenCentralMirror < Base 6 | GOOGLE_MAVEN_MIRROR = Travis::Build.config.maven_central_mirror.output_safe 7 | def apply 8 | sh.raw bash('travis_maven_central_mirror') 9 | sh.raw "travis_maven_central_mirror #{GOOGLE_MAVEN_MIRROR}" 10 | end 11 | 12 | def apply? 13 | config[:os] != 'windows' && !GOOGLE_MAVEN_MIRROR.to_s.empty? 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/maven_https.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | module Travis 3 | module Build 4 | module Appliances 5 | class MavenHttps < Base 6 | def apply 7 | sh.raw bash('travis_maven_https') 8 | sh.raw "travis_maven_https" 9 | end 10 | 11 | def apply? 12 | config[:os] != 'windows' 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/no_ipv6_localhost.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class NoIpv6Localhost < Base 7 | def apply 8 | sh.raw %(sed -e 's/^\\([0-9a-f:]\\+\\s\\)localhost/\\1/' /etc/hosts > /tmp/hosts.tmp && cat /tmp/hosts.tmp | sudo tee /etc/hosts > /dev/null 2>&1) 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/no_world_writable_dirs.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class NoWorldWritableDirs < Base 7 | def apply 8 | sh.cmd <<-EOF 9 | for dir in $(echo $PATH | tr : " "); do 10 | test -d $dir && sudo chmod o-w $dir | grep changed 11 | done 12 | EOF 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/nonblock_pipe.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class NonblockPipe < Base 7 | 8 | def apply 9 | command = <<-EOF 10 | if [[ $TRAVIS_FILTERED = redirect_io ]]; then 11 | cat <<\\EOPY >~/nonblock.py 12 | import os 13 | import sys 14 | import fcntl 15 | 16 | flags_stdout = fcntl.fcntl(sys.stdout, fcntl.F_GETFL) 17 | fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags_stdout&~os.O_NONBLOCK) 18 | 19 | flags_stderr = fcntl.fcntl(sys.stderr, fcntl.F_GETFL) 20 | fcntl.fcntl(sys.stderr, fcntl.F_SETFL, flags_stderr&~os.O_NONBLOCK) 21 | EOPY 22 | python ~/nonblock.py 23 | rm ~/nonblock.py 24 | fi 25 | EOF 26 | 27 | sh.cmd command 28 | end 29 | 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/npm_registry.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class NpmRegistry < Base 7 | def apply? 8 | data[:npm_registry] 9 | end 10 | 11 | def apply 12 | sh.fold "npm_registry" do 13 | sh.export 'NPM_CONFIG_REGISTRY', data[:npm_registry], echo: true 14 | end 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/put_localhost_first.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class PutLocalhostFirst < Base 7 | def apply 8 | # gather names mapped to 127.0.0.1 9 | sh.raw %q(grep '^127\.0\.0\.1' /etc/hosts | sed -e 's/^127\.0\.0\.1\\s\\{1,\\}\\(.*\\)/\1/g' | sed -e 's/localhost \\(.*\\)/\1/g' | tr "\n" " " > /tmp/hosts_127_0_0_1) 10 | # remove lines with 127.0.0.1 11 | sh.raw %q(sed '/^127\.0\.0\.1/d' /etc/hosts > /tmp/hosts_sans_127_0_0_1) 12 | # reconstruct /etc/hosts 13 | sh.raw %q(cat /tmp/hosts_sans_127_0_0_1 | sudo tee /etc/hosts &> /dev/null) 14 | sh.raw %q(echo -n "127.0.0.1 localhost " | sudo tee -a /etc/hosts &> /dev/null) 15 | sh.raw %q({ cat /tmp/hosts_127_0_0_1; echo; } | sudo tee -a /etc/hosts &> /dev/null) 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/redefine_curl.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class RedefineCurl < Base 7 | def apply 8 | sh.raw <<-EOF 9 | function curl() { 10 | command curl --retry 2 -sS "$@" 11 | } 12 | EOF 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/resolvconf.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class Resolvconf < Base 7 | def apply? 8 | linux? 9 | end 10 | 11 | def apply 12 | sh.if 'sudo service resolvconf status >&/dev/null', raw: true do 13 | sh.fold "resolvconf" do 14 | sh.raw <<-EOF 15 | echo "options timeout:1" | sudo tee -a /etc/resolvconf/resolv.conf.d/tail >/dev/null 16 | echo "options attempts:3" | sudo tee -a /etc/resolvconf/resolv.conf.d/tail >/dev/null 17 | sudo service resolvconf restart 18 | EOF 19 | end 20 | end 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/rm_etc_boto_cfg.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class RmEtcBotoCfg < Base 7 | def apply 8 | sh.cmd "rm -f /etc/boto.cfg", sudo: true, assert: false, echo: false 9 | end 10 | 11 | def apply? 12 | !windows? 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/rm_oraclejdk8_symlink.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class RmOraclejdk8Symlink < Base 7 | def apply 8 | symlink = '/usr/lib/jvm/java-8-oracle-amd64' 9 | sh.if "-L #{symlink}" do 10 | sh.cmd "sudo rm -f #{symlink}", echo: false 11 | %W( 12 | ${TRAVIS_HOME}/.jdk_switcher_rc 13 | /opt/jdk_switcher/jdk_switcher.sh 14 | ).each do |jdk_switcher| 15 | sh.if "-f #{jdk_switcher}" do 16 | sh.cmd "source #{jdk_switcher}", echo: false 17 | end 18 | end 19 | end 20 | end 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/rm_riak_source.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class RmRiakSource < Base 7 | def apply 8 | command = <<-EOF 9 | if [[ -d /var/lib/apt/lists && -n $(command -v apt-get) ]]; then 10 | grep -l -i -r basho /etc/apt/sources.list.d | xargs sudo rm -f 11 | fi 12 | EOF 13 | sh.cmd command, echo: false 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/rvm_use.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class RvmUse < Base 7 | def apply 8 | sh.if "$(command -v sw_vers)" do 9 | sh.cmd "rvm use &>/dev/null", echo: false 10 | end 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/set_docker_mtu_and_registry_mirrors.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class SetDockerMtuAndRegistryMirrors < Base 7 | 8 | REGISTRY_URL = Travis::Build.config.registry_url.output_safe.freeze 9 | MTU = Travis::Build.config.docker.mtu.to_i.freeze 10 | 11 | def apply? 12 | linux? 13 | end 14 | 15 | def apply 16 | sh.fold "docker_mtu_and_registry_mirrors" do 17 | sh.raw <<-EOF 18 | sudo test -f /etc/docker/daemon.json 19 | if [[ $? = 0 ]]; then 20 | echo '[{"op":"add","path":"/mtu","value":#{MTU}}]' > mtu.jsonpatch 21 | sudo jsonpatch /etc/docker/daemon.json mtu.jsonpatch > daemon.json 22 | sudo mv daemon.json /etc/docker/daemon.json 23 | else 24 | echo '{"mtu":#{MTU}}' | sudo tee /etc/docker/daemon.json > /dev/null 25 | fi 26 | 27 | if curl --connect-timeout 1 -fsSL -o /dev/null \ 28 | "#{REGISTRY_URL}" &>/dev/null; then 29 | echo '[{"op":"add","path":"/registry-mirrors","value":["#{REGISTRY_URL}"]}]' > registry.jsonpatch 30 | sudo jsonpatch /etc/docker/daemon.json registry.jsonpatch > daemon.json 31 | sudo mv daemon.json /etc/docker/daemon.json 32 | fi 33 | 34 | sudo service docker restart 35 | EOF 36 | end 37 | end 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/set_x.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | require 'travis/rollout' 3 | 4 | module Travis 5 | module Build 6 | module Appliances 7 | class SetX < Base 8 | def apply? 9 | enabled? 10 | end 11 | 12 | def apply 13 | sh.raw 'set -x' 14 | end 15 | 16 | private 17 | 18 | def enabled? 19 | Travis::Rollout.matches?(:set_x, repo: slug) 20 | end 21 | 22 | def slug 23 | data.repository[:slug].to_s 24 | end 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/shell_session_update.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class ShellSessionUpdate < Base 7 | def apply 8 | sh.cmd <<~EOF 9 | if [ "$TRAVIS_OS_NAME" = osx ] && ! declare -f shell_session_update >/dev/null; then 10 | shell_session_update() { :; } 11 | export -f shell_session_update 12 | fi 13 | EOF 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/uninstall_oclint.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class UninstallOclint < Base 7 | def apply 8 | sh.if "$(command -v brew)" do 9 | sh.cmd "brew cask uninstall oclint &>/dev/null", assert: false 10 | sh.if "$? == 0" do 11 | sh.echo "Uninstalled oclint to prevent interference with other packages." 12 | sh.echo "If you need oclint, you must explicitly install it." 13 | end 14 | sh.newline 15 | end 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/update_glibc.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class UpdateGlibc < Base 7 | def apply? 8 | super && Travis::Build.config.update_glibc? 9 | end 10 | 11 | def apply 12 | return unless data.disable_sudo? 13 | sh.if '${TRAVIS_OS_NAME} == linux && ${TRAVIS_DIST} == precise' do 14 | sh.fold "fix.CVE-2015-7547" do 15 | sh.echo 'Forcing update of libc6', ansi: :yellow 16 | sh.cmd 'travis_apt_get_update' 17 | sh.if '${TRAVIS_OS_NAME} != darwin' do 18 | sh.cmd 'sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install libc6' 19 | end 20 | end 21 | end 22 | end 23 | 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/update_heroku.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class UpdateHeroku < Base 7 | def apply 8 | sh.if '("$TRAVIS_DIST" != precise || "$TRAVIS_OS_NAME" == linux) && "$(which heroku)" =~ heroku' do 9 | update_heroku = <<~UPDATE_HEROKU 10 | bash -c ' 11 | cd /usr/lib 12 | (curl -sfSL https://cli-assets.heroku.com/heroku-linux-x64.tar.xz | tar Jx) && 13 | ln -sf /usr/lib/heroku/bin/heroku /usr/bin/heroku 14 | ' 15 | UPDATE_HEROKU 16 | 17 | remove_heroku = <<~REMOVE_HEROKU 18 | bash -c ' 19 | rm -rf /usr/local/heroku 20 | apt-get purge -y heroku-toolbelt heroku &>/dev/null 21 | ' 22 | REMOVE_HEROKU 23 | 24 | sh.cmd update_heroku, sudo: true, echo: false 25 | sh.if "$? -eq 0" do 26 | sh.cmd remove_heroku, sudo: true, echo: false 27 | end 28 | sh.else do 29 | sh.echo "Failed to update Heroku CLI", ansi: :red 30 | end 31 | end 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/update_libssl.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class UpdateLibssl < Base 7 | def apply 8 | sh.if "-n $(command -v lsb_release) && $(lsb_release -cs) = 'precise'" do 9 | sh.fold "update_libssl1.0.0" do 10 | sh.cmd "apt-get install ca-certificates libssl1.0.0", sudo: true, echo: true 11 | end 12 | end 13 | end 14 | 15 | def apply? 16 | super && data.disable_sudo? 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/update_mongo_arch.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class UpdateMongoArch < Base 7 | def apply 8 | command = <<-EOF 9 | if command -v lsb_release &>/dev/null; then 10 | shopt -s nullglob 11 | for f in /etc/apt/sources.list.d/mongodb-*.list; do 12 | grep -vq arch=amd64 "$f" && sudo sed -i 's/^deb /deb [arch=amd64] /' "$f" 13 | done 14 | shopt -u nullglob 15 | fi 16 | EOF 17 | sh.cmd command, echo: false, assert: false, sudo: false 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/validate.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class Validate < Base 7 | MSGS = { 8 | not_found: ['Could not find .travis.yml, using standard configuration.', ansi: :red], 9 | server_error: ['Could not fetch .travis.yml from GitHub.', ansi: :red] 10 | } 11 | 12 | attr_reader :msgs, :result 13 | 14 | def initialize(*) 15 | super 16 | @result = true 17 | @msgs = [] 18 | end 19 | 20 | def apply 21 | validate_config 22 | msgs.each { |msg| sh.echo *msg } 23 | sh.terminate unless result 24 | result 25 | end 26 | 27 | def apply? 28 | true 29 | end 30 | 31 | def time? 32 | false 33 | end 34 | 35 | private 36 | 37 | def validate_config 38 | msg = MSGS[config_status] 39 | msgs << msg if msg 40 | @result = false if config_status == :server_error 41 | end 42 | 43 | def config_status 44 | status = config[:".result"] 45 | status.to_sym if status 46 | end 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/vault_connect.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | require 'travis/services/vault' 3 | 4 | module Travis 5 | module Build 6 | module Appliances 7 | class VaultConnect < Base 8 | ERROR_MESSAGE = ["Failed to connect to the Vault instance. Please verify if:\n* The Vault Token is correct (encrypted, not plain text). \n* The Vault Token is not expired. \n* The Vault can accept connections from the Travis CI build job environments (https://docs.travis-ci.com/user/ip-addresses/).", ansi: :red].freeze 9 | SUCCESS_MESSAGE = ['Connected to Vault instance.', ansi: :green].freeze 10 | 11 | def apply? 12 | @vault = config[:vault] if (config.dig(:vault, :secrets) || []).flatten.any? { |el| el.is_a?(String) } 13 | end 14 | 15 | def apply 16 | Travis::Vault::Connect.call(@vault) 17 | sh.echo *SUCCESS_MESSAGE 18 | sh.export('VAULT_ADDR', @vault[:api_url], echo: true, secure: true) 19 | sh.export('VAULT_TOKEN', @vault[:token], echo: true, secure: true) 20 | rescue Travis::Vault::ConnectionError, ArgumentError, URI::InvalidURIError => _e 21 | sh.echo *ERROR_MESSAGE 22 | sh.terminate 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/vault_keys.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/core_ext/object/blank' 2 | require 'travis/build/appliances/base' 3 | require 'travis/services/vault' 4 | 5 | module Travis 6 | module Build 7 | module Appliances 8 | class VaultKeys < Base 9 | ERROR_MESSAGE = ['Too many keys in fetched data. Probably you provided the root key. Terminating for security reasons.', ansi: :red].freeze 10 | 11 | attr_reader :vault 12 | 13 | def apply? 14 | @vault = config[:vault] if config.dig(:vault, :secrets).present? 15 | end 16 | 17 | def apply 18 | Travis::Vault::Keys.new(self).resolve 19 | rescue Travis::Vault::RootKeyError 20 | sh.echo *ERROR_MESSAGE 21 | sh.terminate 22 | end 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/travis/build/appliances/wait_for_network.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/appliances/base' 2 | 3 | module Travis 4 | module Build 5 | module Appliances 6 | class WaitForNetwork < Base 7 | def apply 8 | return unless Travis::Build.config.wait_for_network_check 9 | sh.raw bash('travis_wait_for_network') 10 | sh.cmd( 11 | "travis_wait_for_network #{wait_retries} #{check_urls.map(&:inspect).join(' ')}", 12 | echo: false 13 | ) 14 | end 15 | 16 | private def check_urls 17 | @check_urls ||= Travis::Build.config.network.check_urls.map do |tmpl| 18 | (tmpl % { 19 | app_host: app_host, 20 | job_id: data.job[:id], 21 | repo: data.slug 22 | }).output_safe 23 | end 24 | end 25 | 26 | private def wait_retries 27 | @wait_retries ||= Integer(Travis::Build.config.network.wait_retries) 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/travis/build/bash.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Build 3 | module Bash 4 | def bash(name, encode: false) 5 | bytes = bash_pathname(name).read.output_safe 6 | return Base64.encode64(bytes) if encode 7 | bytes 8 | end 9 | 10 | private def bash_pathname(name) 11 | Pathname.new(File.expand_path("./bash/#{name}.bash", __dir__)) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_apt_get_options.bash: -------------------------------------------------------------------------------- 1 | travis_apt_get_options() { 2 | # NOTE: set `--allow-.+` options if apt version is >= 1.2 or 2.x+ 3 | apt-get --version | awk ' 4 | $1 == "apt" { 5 | split($2, apt, ".") 6 | if ((apt[1]==1 && apt[2]>=2) || apt[1]>1) { 7 | print "--allow-downgrades --allow-remove-essential --allow-change-held-packages" 8 | } 9 | else { 10 | print "--force-yes" 11 | } 12 | exit 13 | } 14 | ' 15 | } 16 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_apt_get_update.bash: -------------------------------------------------------------------------------- 1 | travis_apt_get_update() { 2 | if ! command -v apt-get &>/dev/null; then 3 | return 4 | fi 5 | 6 | local logdest="${TRAVIS_HOME}/apt-get-update.log" 7 | local opts='-yq' 8 | if [[ "${1}" == debug ]]; then 9 | opts='' 10 | logdest='/dev/stderr' 11 | fi 12 | 13 | sudo rm -rf "${TRAVIS_ROOT}/var/lib/apt/lists/"* 14 | sudo apt-get update ${opts} 2>&1 | tee -a "${logdest}" &>/dev/null 15 | } 16 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_artifacts_install.bash: -------------------------------------------------------------------------------- 1 | travis_artifacts_install() { 2 | local source="https://s3.amazonaws.com/travis-ci-gmbh/artifacts/stable/build/${TRAVIS_OS_NAME}/${TRAVIS_ARCH}/artifacts" 3 | local target="${TRAVIS_HOME}/bin/artifacts" 4 | 5 | if [[ ${TRAVIS_OS_NAME} == "windows" ]]; then 6 | source="${source}.exe" 7 | fi 8 | 9 | mkdir -p "$(dirname "${target}")" 10 | travis_download "${source}" "${target}" 11 | chmod +x "${target}" 12 | PATH="$(dirname "${target}"):$PATH" artifacts -v 13 | } 14 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_assert.bash: -------------------------------------------------------------------------------- 1 | travis_assert() { 2 | local result="${1:-${?}}" 3 | if [[ "${result}" -ne 0 ]]; then 4 | printf "${ANSI_RED}The command \"%s\" failed and exited with ${result} during %s.${ANSI_RESET}\\n" "${TRAVIS_CMD}" "${TRAVIS_STAGE}" 5 | printf "\\nYour build has been stopped.\\n" 6 | travis_terminate 2 7 | fi 8 | } 9 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_bash_qsort_numeric.bash: -------------------------------------------------------------------------------- 1 | travis_bash_qsort_numeric() { 2 | local pivot i smaller=() larger=() 3 | travis_bash_qsort_numeric_ret=() 4 | (($# == 0)) && return 0 5 | pivot="${1}" 6 | shift 7 | for i; do 8 | if [[ "${i%%_*}" -lt "${pivot%%_*}" ]]; then 9 | smaller+=("${i}") 10 | else 11 | larger+=("${i}") 12 | fi 13 | done 14 | travis_bash_qsort_numeric "${smaller[@]}" 15 | smaller=("${travis_bash_qsort_numeric_ret[@]}") 16 | travis_bash_qsort_numeric "${larger[@]}" 17 | larger=("${travis_bash_qsort_numeric_ret[@]}") 18 | travis_bash_qsort_numeric_ret=("${smaller[@]}" "${pivot}" "${larger[@]}") 19 | } 20 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_cleanup.bash: -------------------------------------------------------------------------------- 1 | travis_cleanup() { 2 | if [[ -n $SSH_AGENT_PID ]]; then 3 | kill "$SSH_AGENT_PID" &>/dev/null 4 | fi 5 | } 6 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_decrypt.bash: -------------------------------------------------------------------------------- 1 | travis_decrypt() { 2 | echo "${1}" | 3 | base64 -d | 4 | openssl rsautl -decrypt -inkey "${TRAVIS_HOME}/.ssh/id_rsa.repo" 5 | } 6 | 7 | decrypt() { 8 | travis_decrypt "${@}" 9 | } 10 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_disable_ssh_roaming.bash: -------------------------------------------------------------------------------- 1 | travis_disable_ssh_roaming() { 2 | mkdir -p "${TRAVIS_HOME}/.ssh" 3 | chmod 0700 "${TRAVIS_HOME}/.ssh" 4 | touch "${TRAVIS_HOME}/.ssh/config" 5 | echo -e "Host *\\n UseRoaming no\\n" | 6 | cat - "${TRAVIS_HOME}/.ssh/config" >"${TRAVIS_HOME}/.ssh/config.tmp" && 7 | mv "${TRAVIS_HOME}/.ssh/config.tmp" "${TRAVIS_HOME}/.ssh/config" 8 | } 9 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_disable_sudo.bash: -------------------------------------------------------------------------------- 1 | travis_disable_sudo() { 2 | local fake_sudo_dest="${TRAVIS_TMPDIR}/fake-sudo" 3 | local real_sudo 4 | real_sudo="$(command -v sudo)" 5 | 6 | sudo -n sh -c " 7 | chmod 4755 ${fake_sudo_dest} 8 | chown root:root ${fake_sudo_dest} 9 | mv ${fake_sudo_dest} ${real_sudo} 10 | find ${TRAVIS_ROOT} \\( -perm -4000 -o -perm -2000 \\) \\ 11 | -a ! -name sudo \\ 12 | -exec chmod a-s {} \\; 2>/dev/null && 13 | sed -e 's/^%.*//' -i.bak ${TRAVIS_ROOT}/etc/sudoers && 14 | rm -f ${TRAVIS_ROOT}/etc/sudoers.d/travis 15 | " 16 | } 17 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_download.bash: -------------------------------------------------------------------------------- 1 | travis_download() { 2 | local src="${1}" 3 | local dst="${2}" 4 | 5 | if curl --version &>/dev/null; then 6 | curl -fsSL --connect-timeout 1 "${src}" -o "${dst}" 2>/dev/null 7 | return "${?}" 8 | fi 9 | 10 | if wget --version &>/dev/null; then 11 | wget --connect-timeout 1 -q "${src}" -O "${dst}" 2>/dev/null 12 | return "${?}" 13 | fi 14 | 15 | return 1 16 | } 17 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_export_go.bash: -------------------------------------------------------------------------------- 1 | travis_export_go() { 2 | if [[ ! "${1}" ]]; then 3 | echo 'Missing go version positional argument' >&2 4 | return 86 5 | fi 6 | 7 | if [[ ! "${2}" ]]; then 8 | echo 'Missing go import path positional argument' >&2 9 | return 86 10 | fi 11 | 12 | export TRAVIS_GO_VERSION="${1}" 13 | export TRAVIS_GO_IMPORT_PATH="${2}" 14 | 15 | export GIMME_GO_VERSION="${TRAVIS_GO_VERSION}" 16 | : "${GOMAXPROCS:=$(nproc 2>/dev/null || echo 2)}" 17 | export GOMAXPROCS 18 | 19 | : "${GO111MODULE:=auto}" 20 | export GO111MODULE 21 | } 22 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_fake_sudo.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | main() { 4 | if [[ -f "${HOME}/.sudo-run" ]]; then 5 | exit 1 6 | fi 7 | 8 | OPTIND=1 9 | while getopts "v" opt; do 10 | case "${opt}" in 11 | v) 12 | QUIET=1 13 | ;; 14 | *) 15 | : 16 | ;; 17 | esac 18 | done 19 | 20 | shift "$((OPTIND - 1))" 21 | 22 | if [[ "${QUIET}" != 1 ]]; then 23 | echo -e "\\033[33;1mThis job is running on container-based infrastructure, which does not allow use of 'sudo', setuid, and setgid executables.\\033[0m 24 | \\033[33;1mIf you require sudo, add 'sudo: required' to your .travis.yml\\033[0m 25 | " 26 | fi 27 | 28 | touch "${HOME}/.sudo-run" 29 | exit 1 30 | } 31 | 32 | main "${@}" 33 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_find_jdk_path.bash: -------------------------------------------------------------------------------- 1 | travis_find_jdk_path() { 2 | local vendor version jdkpath result jdk 3 | jdk="$1" 4 | vendor="$2" 5 | version="$3" 6 | if [[ "$vendor" == "openjdk" ]]; then 7 | apt_glob="/usr/lib/jvm/java-1.${version}.*openjdk*" 8 | elif [[ "$vendor" == "oracle" ]]; then 9 | apt_glob="/usr*/lib/jvm/java-${version}-oracle" 10 | fi 11 | shopt -s nullglob 12 | for jdkpath in /usr*/local/lib/jvm/"$jdk" $apt_glob; do 13 | [[ ! -d "$jdkpath" ]] && continue 14 | result="$jdkpath" 15 | break 16 | done 17 | shopt -u nullglob 18 | echo "$result" 19 | } 20 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_fold.bash: -------------------------------------------------------------------------------- 1 | travis_fold() { 2 | local action="${1}" 3 | local name="${2}" 4 | echo -en "travis_fold:${action}:${name}\\r${ANSI_CLEAR}" 5 | } 6 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_footer.bash: -------------------------------------------------------------------------------- 1 | travis_footer() { 2 | : "${TRAVIS_TEST_RESULT:=86}" 3 | echo -e "\\nDone. Your build exited with ${TRAVIS_TEST_RESULT}." 4 | travis_terminate "${TRAVIS_TEST_RESULT}" 5 | } 6 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_getaddrinfo.bash: -------------------------------------------------------------------------------- 1 | travis_getaddrinfo() { 2 | local nodename="${1}" 3 | 4 | if [[ ! "${nodename}" ]]; then 5 | return 6 | fi 7 | 8 | ruby -rsocket <&2 6 | else 7 | for v in "${TRAVIS_GHC_ROOT}"/*/; do 8 | v=${v%%/} 9 | v=${v##*/} 10 | if [[ ! -d "${TRAVIS_GHC_ROOT}/${v}" ]]; then 11 | continue 12 | fi 13 | if [[ "${v}" == ${search}* ]]; then 14 | echo "${v}" 15 | return 0 16 | fi 17 | done 18 | echo -e "${ANSI_RED}No such ghc version '${search}'.${ANSI_RESET}" >&2 19 | fi 20 | echo -e "${ANSI_YELLOW}Using default ghc version '${TRAVIS_GHC_DEFAULT}'.${ANSI_RESET}" >&2 21 | echo "${TRAVIS_GHC_DEFAULT}" 22 | return 1 23 | } 24 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_ghc_install.bash: -------------------------------------------------------------------------------- 1 | travis_ghc_install() { 2 | local ghc_version="${1}" 3 | local cabal_version="${2}" 4 | if [[ ! "${ghc_version}" ]]; then 5 | echo -e "\\n${ANSI_RED}No ghc version given.${ANSI_RESET}" >&2 6 | return 1 7 | fi 8 | if [[ ! "${cabal_version}" ]]; then 9 | echo -e "\\n${ANSI_RED}No cabal version given.${ANSI_RESET}" >&2 10 | return 1 11 | fi 12 | if ! sudo date &>/dev/null; then 13 | return 1 14 | fi 15 | if [[ ! -f '<%= root %>/etc/apt/sources.list.d/hvr-ghc.list' ]]; then 16 | echo -e "\\n${ANSI_GREEN}Adding ppa:hvr/ghc.${ANSI_RESET}" >&2 17 | sudo apt-add-repository -y ppa:hvr/ghc 18 | fi 19 | travis_apt_get_update 20 | if sudo apt-get install -yq "ghc-${ghc_version}"; then 21 | echo -e "\\n${ANSI_GREEN}Successfully installed 'ghc-${ghc_version}'.${ANSI_RESET}" >&2 22 | else 23 | return 1 24 | fi 25 | if sudo apt-get install -yq "cabal-install-${cabal_version}"; then 26 | echo -e "\\n${ANSI_GREEN}Successfully installed 'cabal-install-${cabal_version}'.${ANSI_RESET}" >&2 27 | return 0 28 | fi 29 | return 1 30 | } 31 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_ghc_setup_env.bash: -------------------------------------------------------------------------------- 1 | travis_ghc_setup_env() { 2 | : "${TRAVIS_GHC_DEFAULT:=7.10.3}" 3 | : "${TRAVIS_GHC_ROOT:=${TRAVIS_ROOT}/usr/local/ghc}" 4 | 5 | export TRAVIS_GHC_DEFAULT 6 | export TRAVIS_GHC_ROOT 7 | 8 | if [[ ! -d "${TRAVIS_GHC_ROOT}" && -d "${TRAVIS_ROOT}/opt/ghc" ]]; then 9 | export TRAVIS_GHC_ROOT="${TRAVIS_ROOT}/opt/ghc" 10 | fi 11 | } 12 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_has_makefile.bash: -------------------------------------------------------------------------------- 1 | travis_has_makefile() { 2 | : "${TRAVIS_BUILD_DIR:=.}" 3 | if [[ -f "${TRAVIS_BUILD_DIR}/GNUmakefile" || -f "${TRAVIS_BUILD_DIR}/makefile" || -f "${TRAVIS_BUILD_DIR}/Makefile" || -f "${TRAVIS_BUILD_DIR}/BSDmakefile" ]]; then 4 | return 0 5 | fi 6 | return 1 7 | } 8 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_install_go_dependencies.bash: -------------------------------------------------------------------------------- 1 | travis_install_go_dependencies() { 2 | : "${GIMME_GO_VERSION:=${1}}" 3 | export GIMME_GO_VERSION 4 | 5 | local gobuild_args 6 | IFS=" " read -r -a gobuild_args <<<"${2}" 7 | 8 | __travis_go_handle_godep_usage 9 | 10 | if travis_has_makefile; then 11 | echo 'Makefile detected' 12 | else 13 | local has_t 14 | for arg in "${gobuild_args[@]}"; do 15 | if [[ "${arg}" == "-t" ]]; then 16 | has_t=1 17 | fi 18 | done 19 | 20 | if [[ ! "${has_t}" ]]; then 21 | gobuild_args=("${gobuild_args[@]}" -t) 22 | fi 23 | 24 | travis_cmd "go get ${gobuild_args[*]} ./..." --retry 25 | fi 26 | } 27 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_internal_ruby.bash: -------------------------------------------------------------------------------- 1 | travis_internal_ruby() { 2 | if ! type rvm &>/dev/null; then 3 | # shellcheck source=/dev/null 4 | source "${TRAVIS_HOME}/.rvm/scripts/rvm" &>/dev/null 5 | fi 6 | local i selected_ruby rubies_array_sorted rubies_array_len 7 | local rubies_array=() 8 | while IFS=$'\n' read -r line; do 9 | rubies_array+=("${line}") 10 | done < <( 11 | rvm list strings | 12 | while read -r v; do 13 | if [[ ! "${v}" =~ ${TRAVIS_INTERNAL_RUBY_REGEX} ]]; then 14 | continue 15 | fi 16 | v="${v//ruby-/}" 17 | v="${v%%-*}" 18 | echo "$(travis_vers2int "${v}")_${v}" 19 | done 20 | ) 21 | travis_bash_qsort_numeric "${rubies_array[@]}" 22 | rubies_array_sorted=("${travis_bash_qsort_numeric_ret[@]}") 23 | rubies_array_len="${#rubies_array_sorted[@]}" 24 | if ((rubies_array_len <= 0)); then 25 | echo 'default' 26 | else 27 | i=$((rubies_array_len - 1)) 28 | selected_ruby="${rubies_array_sorted[${i}]}" 29 | selected_ruby="${selected_ruby##*_}" 30 | echo "${selected_ruby:-default}" 31 | fi 32 | } 33 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_jigger.bash: -------------------------------------------------------------------------------- 1 | travis_jigger() { 2 | local cmd_pid="${1}" 3 | shift 4 | local timeout="${1}" 5 | shift 6 | local count=0 7 | 8 | echo -e "\\n" 9 | 10 | while [[ "${count}" -lt "${timeout}" ]]; do 11 | count="$((count + 1))" 12 | echo -ne "Still running (${count} of ${timeout}): ${*}\\r" 13 | sleep 60 14 | done 15 | 16 | echo -e "\\n${ANSI_RED}Timeout (${timeout} minutes) reached. Terminating \"${*}\"${ANSI_RESET}\\n" 17 | kill -9 "${cmd_pid}" 18 | } 19 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_jinfo_file.bash: -------------------------------------------------------------------------------- 1 | travis_jinfo_file() { 2 | local vendor version 3 | vendor="$1" 4 | version="$2" 5 | if [[ "$vendor" == oracle ]]; then 6 | echo ".java-${version}-${vendor}.jinfo" 7 | elif [[ "$vendor" == openjdk ]]; then 8 | echo ".java-1.${version}.*-${vendor}-*.jinfo" 9 | fi 10 | } 11 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_key.bash: -------------------------------------------------------------------------------- 1 | travis_key() { 2 | local var_name="TRAVIS_$1" 3 | if [[ ! -z ${!var_name+x} ]]; then 4 | echo "${!var_name}" | base64 --decode >"$2" 5 | chmod 0600 "$2" 6 | else 7 | echo "Required keys " "$1" " was not found. Please verify your account settings or correct build configuration." 8 | exit 1 9 | fi 10 | } 11 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_maven_central_mirror.bash: -------------------------------------------------------------------------------- 1 | travis_maven_central_mirror() { 2 | local google_mirror=$1 3 | if [[ ! -f $HOME/.m2/settings.xml ]]; then return; fi 4 | 5 | ruby -rrexml/document -e "begin 6 | doc=REXML::Document.new(File.read('$HOME/.m2/settings.xml')); doc.elements['/settings'] << REXML::Document.new(' 7 | 8 | google-maven-central 9 | GCS Maven Central mirror 10 | $google_mirror 11 | central 12 | 13 | ') 14 | doc.write 15 | rescue 16 | nil 17 | end" >settings.xml 18 | if [[ -s settings.xml ]]; then 19 | mv settings.xml "${HOME}"/.m2/settings.xml 20 | fi 21 | } 22 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_maven_https.bash: -------------------------------------------------------------------------------- 1 | travis_maven_https() { 2 | if [[ ! -f $HOME/.m2/settings.xml ]]; then return; fi 3 | 4 | ruby -rrexml/document -e "begin 5 | doc=REXML::Document.new(File.read('$HOME/.m2/settings.xml')); 6 | doc.get_elements('//url[starts-with(.,\"http://\")]').each do |e| 7 | url = e.text 8 | e.text = url.gsub('http://','https://') 9 | end 10 | doc.write 11 | rescue 12 | nil 13 | end" >settings.xml 14 | if [[ -s settings.xml ]]; then 15 | mv settings.xml "${HOME}"/.m2/settings.xml 16 | fi 17 | } 18 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_munge_apt_sources.bash: -------------------------------------------------------------------------------- 1 | travis_munge_apt_sources() { 2 | if ! command -v apt-get &>/dev/null; then 3 | return 4 | fi 5 | 6 | local src="${TRAVIS_ROOT}/etc/apt/sources.list" 7 | src="${src//\/\//\/}" 8 | local tmp_dest="${TRAVIS_TMPDIR}/etc-apt-sources.list" 9 | tmp_dest="${tmp_dest//\/\//\/}" 10 | 11 | if [[ ! -f "${src}" ]]; then 12 | return 13 | fi 14 | 15 | local mirror 16 | for entry in "${_TRAVIS_APT_MIRRORS_BY_INFRASTRUCTURE[@]}"; do 17 | if [[ "${entry%%::*}" == "${TRAVIS_INFRA}" ]]; then 18 | mirror="${entry##*::}" 19 | fi 20 | done 21 | 22 | if [[ ! "${mirror}" ]]; then 23 | return 24 | fi 25 | 26 | sed -e "s,http://.*\\.ubuntu\\.com/ubuntu/,${mirror}," \ 27 | "${src}" >"${tmp_dest}" 28 | sudo mv "${src}" "${src}.travis-build.bak" 29 | sudo mv "${tmp_dest}" "${src}" 30 | } 31 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_nanoseconds.bash: -------------------------------------------------------------------------------- 1 | travis_nanoseconds() { 2 | local cmd='date' 3 | local format='+%s%N' 4 | 5 | if hash gdate >/dev/null 2>&1; then 6 | cmd='gdate' 7 | elif [[ "${TRAVIS_OS_NAME}" == osx ]]; then 8 | format='+%s000000000' 9 | fi 10 | 11 | "${cmd}" -u "${format}" 12 | } 13 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_preamble.bash: -------------------------------------------------------------------------------- 1 | travis_preamble() { 2 | if [[ -s "${TRAVIS_ROOT}/etc/profile" ]]; then 3 | # shellcheck source=/dev/null 4 | source "${TRAVIS_ROOT}/etc/profile" 5 | fi 6 | 7 | if [[ -s "${TRAVIS_HOME}/.bash_profile" ]]; then 8 | # shellcheck source=/dev/null 9 | source "${TRAVIS_HOME}/.bash_profile" 10 | fi 11 | 12 | mkdir -p "${TRAVIS_HOME}/.travis" 13 | echo "source ${TRAVIS_HOME}/.travis/job_stages" >>"${TRAVIS_HOME}/.bashrc" 14 | 15 | mkdir -p "${TRAVIS_BUILD_DIR}" 16 | cd "${TRAVIS_BUILD_DIR}" || exit 86 17 | } 18 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_remove_from_path.bash: -------------------------------------------------------------------------------- 1 | travis_remove_from_path() { 2 | local target="$1" 3 | PATH="$(echo "$PATH" | 4 | sed -e "s,\\(:\\|^\\)$target\\(:\\|$\\),:,g" \ 5 | -e 's/::\+/:/g' \ 6 | -e 's/:$//' \ 7 | -e 's/^://')" 8 | } 9 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_result.bash: -------------------------------------------------------------------------------- 1 | travis_result() { 2 | local result="${1}" 3 | export TRAVIS_TEST_RESULT=$((${TRAVIS_TEST_RESULT:-0} | $((result != 0)))) 4 | 5 | if [[ "${result}" -eq 0 ]]; then 6 | printf "${ANSI_GREEN}The command \"%s\" exited with ${result}.${ANSI_RESET}\\n" "${TRAVIS_CMD}" 7 | else 8 | printf "${ANSI_RED}The command \"%s\" exited with ${result}.${ANSI_RESET}\\n" "${TRAVIS_CMD}" 9 | fi 10 | } 11 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_retry.bash: -------------------------------------------------------------------------------- 1 | travis_retry() { 2 | local result=0 3 | local count=1 4 | while [[ "${count}" -le 3 ]]; do 5 | [[ "${result}" -ne 0 ]] && { 6 | echo -e "\\n${ANSI_RED}The command \"${*}\" failed. Retrying, ${count} of 3.${ANSI_RESET}\\n" >&2 7 | } 8 | # run the command in a way that doesn't disable setting `errexit` 9 | "${@}" 10 | result="${?}" 11 | if [[ $result -eq 0 ]]; then break; fi 12 | count="$((count + 1))" 13 | sleep 1 14 | done 15 | 16 | [[ "${count}" -gt 3 ]] && { 17 | echo -e "\\n${ANSI_RED}The command \"${*}\" failed 3 times.${ANSI_RESET}\\n" >&2 18 | } 19 | 20 | return "${result}" 21 | } 22 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_script_go.bash: -------------------------------------------------------------------------------- 1 | travis_script_go() { 2 | local gobuild_args="${1}" 3 | 4 | if travis_has_makefile; then 5 | travis_cmd make 6 | else 7 | travis_cmd "go test ${gobuild_args} ./..." 8 | fi 9 | } 10 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_setup_apt_proxy.bash: -------------------------------------------------------------------------------- 1 | travis_setup_apt_proxy() { 2 | if [[ ! "${TRAVIS_APT_PROXY}" ]]; then 3 | return 4 | fi 5 | 6 | local dest_dir='/etc/apt/apt.conf.d' 7 | 8 | if [[ ! -d "${dest_dir}" ]]; then 9 | return 10 | fi 11 | 12 | if ! sudo -n echo &>/dev/null; then 13 | return 14 | fi 15 | 16 | if ! curl --connect-timeout 1 -fsSL -o /dev/null \ 17 | "${TRAVIS_APT_PROXY}/__squignix_health__" &>/dev/null; then 18 | return 19 | fi 20 | 21 | ( 22 | cat </dev/null 33 | } 34 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_setup_go.bash: -------------------------------------------------------------------------------- 1 | travis_setup_go() { 2 | local go_version="${TRAVIS_GO_VERSION:-${1}}" 3 | local go_import_path="${TRAVIS_GO_IMPORT_PATH:-${2}}" 4 | 5 | if [[ ! "${go_version}" ]]; then 6 | echo 'Missing TRAVIS_GO_VERSION' >&2 7 | return 86 8 | fi 9 | 10 | if [[ ! "${go_import_path}" ]]; then 11 | echo 'Missing TRAVIS_GO_IMPORT_PATH' >&2 12 | return 86 13 | fi 14 | 15 | if ! command -v go &>/dev/null; then 16 | echo "Go is not installed. Installing..." 17 | travis_cmd "choco install golang --version=${go_version} -y" --echo 18 | travis_cmd "export GOROOT=\"C:\\Program Files\\Go\"" --echo 19 | travis_cmd "export PATH=\"/c/Program Files/Go/bin:$PATH\"" --echo 20 | travis_cmd "export GO111MODULE=\"${GO111MODULE}\"" --echo 21 | else 22 | echo "Go is already installed. Setting up specific version..." 23 | travis_cmd "export GOPATH=\"${TRAVIS_HOME}/gopath\"" --echo 24 | travis_cmd "export PATH=\"${TRAVIS_HOME}/gopath/bin:${PATH}\"" --echo 25 | travis_cmd "export GO111MODULE=\"${GO111MODULE}\"" --echo 26 | travis_cmd "go install \"golang.org/dl/go${go_version}@latest\"" --echo 27 | travis_cmd "\"go${go_version}\" download" --echo 28 | travis_cmd "sudo ln -s \"${TRAVIS_HOME}/gopath/bin/go${go_version}\" \"${TRAVIS_HOME}/gopath/bin/go\"" --echo 29 | travis_cmd "export GOROOT=\$(go${go_version} env GOROOT)" --echo 30 | travis_cmd "export PATH=\${GOROOT}/bin:\${PATH}" --echo 31 | fi 32 | 33 | mkdir -p "$(dirname "${GOPATH}/src/${go_import_path}")" 34 | ln -s "${TRAVIS_BUILD_DIR}" "$GOPATH/src/${go_import_path}" 35 | } 36 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_setup_java.bash: -------------------------------------------------------------------------------- 1 | travis_setup_java() { 2 | local jdkpath jdk vendor version 3 | jdk="$1" 4 | vendor="$2" 5 | version="$3" 6 | jdkpath="$(travis_find_jdk_path "$jdk" "$vendor" "$version")" 7 | if [[ -z "$jdkpath" ]]; then 8 | if [[ "$TRAVIS_OS_NAME" == osx ]]; then 9 | java -version 2>&1 | awk -v vendor="$vendor" -v version="$version" -F'"' ' 10 | BEGIN { 11 | v = "openjdk" 12 | if(version<9) { version = "1\\."version } 13 | version = "^"version"\\." 14 | } 15 | /HotSpot/ { v = "oracle" } 16 | /version/ { if ($2 !~ version) e++ } 17 | END { 18 | if (vendor !=v ) e++ 19 | exit e 20 | } 21 | ' && 22 | return 23 | fi 24 | travis_install_jdk "$jdk" "$vendor" "$version" 25 | elif compgen -G "${jdkpath%/*}/$(travis_jinfo_file "$vendor" "$version")" &>/dev/null && 26 | declare -f jdk_switcher &>/dev/null; then 27 | travis_cmd "jdk_switcher use \"$jdk\"" --echo --assert 28 | if [[ -f ~/.bash_profile.d/travis_jdk.bash ]]; then 29 | sed -i '/export \(PATH\|JAVA_HOME\)=/d' ~/.bash_profile.d/travis_jdk.bash 30 | fi 31 | else 32 | export JAVA_HOME="$jdkpath" 33 | export PATH="$JAVA_HOME/bin:$PATH" 34 | if [[ -f ~/.bash_profile.d/travis_jdk.bash ]]; then 35 | sed -i "/export JAVA_HOME=/s,=.\\+,=\"$JAVA_HOME\"," ~/.bash_profile.d/travis_jdk.bash 36 | fi 37 | fi 38 | } 39 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_stop_sauce_connect.bash: -------------------------------------------------------------------------------- 1 | travis_stop_sauce_connect() { 2 | if [[ "${TRAVIS_SAUCE_CONNECT_PID}" == unset ]]; then 3 | echo 'No running Sauce Connect tunnel found' 4 | return 1 5 | fi 6 | 7 | kill "${TRAVIS_SAUCE_CONNECT_PID}" 8 | 9 | for i in 0 1 2 3 4 5 6 7 8 9; do 10 | if kill -0 "${TRAVIS_SAUCE_CONNECT_PID}" &>/dev/null; then 11 | echo "Waiting for graceful Sauce Connect shutdown ($((i + 1))/10)" 12 | sleep 1 13 | else 14 | echo 'Sauce Connect shutdown complete' 15 | return 0 16 | fi 17 | done 18 | 19 | if kill -0 "${TRAVIS_SAUCE_CONNECT_PID}" &>/dev/null; then 20 | echo 'Forcefully terminating Sauce Connect' 21 | kill -9 "${TRAVIS_SAUCE_CONNECT_PID}" &>/dev/null || true 22 | fi 23 | } 24 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_temporary_hacks.bash: -------------------------------------------------------------------------------- 1 | travis_temporary_hacks() { 2 | if [[ ! "${TRAVIS_OS_NAME}" ]]; then 3 | return 4 | fi 5 | 6 | "_travis_temporary_hacks_${TRAVIS_OS_NAME}" &>/dev/null || true 7 | } 8 | 9 | _travis_temporary_hacks_linux() { 10 | for troublesome_source in \ 11 | rabbitmq-source.list \ 12 | travis_ci_zeromq3.list \ 13 | neo4j.list; do 14 | sudo rm -f "${TRAVIS_ROOT}/etc/apt/sources.list.d/${troublesome_source}" 15 | done 16 | } 17 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_terminate.bash: -------------------------------------------------------------------------------- 1 | travis_terminate() { 2 | if [[ ! "${TRAVIS_OS_NAME}" ]]; then 3 | return 4 | fi 5 | 6 | _travis_terminate_agent 7 | "_travis_terminate_${TRAVIS_OS_NAME}" "${@}" 8 | } 9 | 10 | _travis_terminate_linux() { 11 | _travis_terminate_unix "${@}" 12 | } 13 | 14 | _travis_terminate_osx() { 15 | _travis_terminate_unix "${@}" 16 | } 17 | 18 | _travis_terminate_freebsd() { 19 | _travis_terminate_unix "${@}" 20 | } 21 | 22 | _travis_terminate_unix() { 23 | set +e 24 | [[ "${TRAVIS_FILTERED}" == redirect_io && -e /dev/fd/9 ]] && 25 | sync && 26 | command exec 1>&9 2>&9 9>&- && 27 | sync 28 | pgrep -u "${USER}" | grep -v -w "${$}" >"${TRAVIS_TMPDIR}/pids_after" 29 | awk 'NR==FNR{a[$1]++;next};!($1 in a)' "${TRAVIS_TMPDIR}"/pids_{before,after} | 30 | xargs kill &>/dev/null || true 31 | pkill -9 -P "${$}" &>/dev/null || true 32 | exit "${1}" 33 | } 34 | 35 | _travis_terminate_windows() { 36 | # TODO: find all child processes and exit via ... powershell? 37 | exit "${1}" 38 | } 39 | 40 | _travis_terminate_agent() { 41 | [ ! -f /tmp/travis/agent.pid ] && return 42 | pid=$(cat /tmp/travis/agent.pid) 43 | 44 | kill "$pid" &>/dev/null 45 | counter=500 46 | while test $((counter--)) -ne 0 -a -f /tmp/travis/agent.pid; do 47 | sleep 0.1 48 | done 49 | 50 | [ -z ${TRAVIS_AGENT_DEBUG+x} ] && return 51 | echo 52 | travis_fold start agent.debug 53 | echo 'cat /tmp/travis/agent.log' 54 | cat /tmp/travis/agent.log 55 | travis_fold end agent.debug 56 | } 57 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_time_finish.bash: -------------------------------------------------------------------------------- 1 | travis_time_finish() { 2 | local result="${?}" 3 | local travis_timer_end_time 4 | local event="${1}" 5 | travis_timer_end_time="$(travis_nanoseconds)" 6 | local duration 7 | duration="$((travis_timer_end_time - TRAVIS_TIMER_START_TIME))" 8 | echo -en "travis_time:end:${TRAVIS_TIMER_ID}:start=${TRAVIS_TIMER_START_TIME},finish=${travis_timer_end_time},duration=${duration},event=${event}\\r${ANSI_CLEAR}" 9 | return "${result}" 10 | } 11 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_time_start.bash: -------------------------------------------------------------------------------- 1 | travis_time_start() { 2 | TRAVIS_TIMER_ID="$(printf %08x $((RANDOM * RANDOM)))" 3 | TRAVIS_TIMER_START_TIME="$(travis_nanoseconds)" 4 | export TRAVIS_TIMER_ID TRAVIS_TIMER_START_TIME 5 | echo -en "travis_time:start:$TRAVIS_TIMER_ID\\r${ANSI_CLEAR}" 6 | } 7 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_trace_span.bash: -------------------------------------------------------------------------------- 1 | travis_trace_span() { 2 | local result="${?}" 3 | local template="${1}" 4 | local timestamp 5 | timestamp="$(travis_nanoseconds)" 6 | template="${template/__TRAVIS_TIMESTAMP__/${timestamp}}" 7 | template="${template/__TRAVIS_STATUS__/${result}}" 8 | echo "${template}" >>/tmp/build.trace 9 | return "${result}" 10 | } 11 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_vers2int.bash: -------------------------------------------------------------------------------- 1 | travis_vers2int() { 2 | local args 3 | read -r -a args <<<"$(echo "${1}" | grep --only '^[0-9\.][0-9\.]*' | tr '.' ' ')" 4 | printf '1%03d%03d%03d%03d' "${args[@]}" 5 | } 6 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_wait.bash: -------------------------------------------------------------------------------- 1 | travis_wait() { 2 | local timeout="${1}" 3 | 4 | if [[ "${timeout}" =~ ^[0-9]+$ ]]; then 5 | shift 6 | else 7 | timeout=20 8 | fi 9 | 10 | local cmd=("${@}") 11 | local log_file="travis_wait_${$}.log" 12 | 13 | "${cmd[@]}" &>"${log_file}" & 14 | local cmd_pid="${!}" 15 | 16 | travis_jigger "${!}" "${timeout}" "${cmd[@]}" & 17 | local jigger_pid="${!}" 18 | local result 19 | 20 | { 21 | wait "${cmd_pid}" 2>/dev/null 22 | result="${?}" 23 | ps -p"${jigger_pid}" &>/dev/null && kill "${jigger_pid}" 24 | } 25 | 26 | if [[ "${result}" -eq 0 ]]; then 27 | printf "\\n${ANSI_GREEN}The command %s exited with ${result}.${ANSI_RESET}\\n" "${cmd[*]}" 28 | else 29 | printf "\\n${ANSI_RED}The command %s exited with ${result}.${ANSI_RESET}\\n" "${cmd[*]}" 30 | fi 31 | 32 | echo -e "\\n${ANSI_GREEN}Log:${ANSI_RESET}\\n" 33 | cat "${log_file}" 34 | 35 | return "${result}" 36 | } 37 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_wait_for_network.bash: -------------------------------------------------------------------------------- 1 | travis_wait_for_network() { 2 | local wait_retries="${1}" 3 | local count=0 4 | shift 5 | local urls=("${@}") 6 | 7 | while [[ "${count}" -lt "${wait_retries}" ]]; do 8 | local confirmed=0 9 | for url in "${urls[@]}"; do 10 | if travis_download "${url}" /dev/null; then 11 | confirmed=$((confirmed + 1)) 12 | fi 13 | done 14 | 15 | if [[ "${#urls[@]}" -eq "${confirmed}" ]]; then 16 | return 17 | fi 18 | 19 | count=$((count + 1)) 20 | sleep 1 21 | done 22 | 23 | echo -e "${ANSI_RED}Timeout waiting for network availability.${ANSI_RESET}" 24 | } 25 | -------------------------------------------------------------------------------- /lib/travis/build/bash/travis_whereami.bash: -------------------------------------------------------------------------------- 1 | travis_whereami() { 2 | curl -sSL -H 'Accept: text/plain' \ 3 | "${TRAVIS_WHEREAMI_URL:-https://whereami.travis-ci.com}" 4 | } 5 | -------------------------------------------------------------------------------- /lib/travis/build/env.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/env/builtin' 2 | require 'travis/build/env/config' 3 | require 'travis/build/env/settings' 4 | require 'travis/build/env/var' 5 | 6 | module Travis 7 | module Build 8 | class Env 9 | GROUPS = [Builtin, Settings, Config] 10 | 11 | attr_reader :data 12 | 13 | def initialize(data) 14 | @data = data 15 | end 16 | 17 | def groups 18 | @groups ||= GROUPS.map { |const| const.new(self, data) } 19 | end 20 | 21 | def announce? 22 | groups.any?(&:announce?) 23 | end 24 | 25 | def secure_env_vars? 26 | data.secure_env? && groups.reject(&:builtin?).any?(&:secure_vars?) 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/travis/build/env/base.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | module Travis 4 | module Build 5 | class Env 6 | class Base < Struct.new(:env, :data) 7 | extend Forwardable 8 | 9 | def_delegators :data, :config, :job 10 | 11 | def to_vars(type, args) 12 | vars = Array(args).map { |arg| to_var(type, *arg) }.select(&:valid?) 13 | vars = vars.reject(&:secure?) unless data.secure_env? 14 | vars 15 | end 16 | 17 | def to_var(type, key, value, options = {}) 18 | Var.new(key, value, options.merge(type: type)) 19 | end 20 | 21 | def builtin? 22 | is_a?(Builtin) 23 | end 24 | 25 | def announce? 26 | !builtin? && vars.length > 0 27 | end 28 | 29 | def secure_vars? 30 | vars.any?(&:secure?) 31 | end 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/travis/build/env/config.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/env/base' 2 | 3 | module Travis 4 | module Build 5 | class Env 6 | class Config < Base 7 | def source 8 | '.travis.yml' 9 | end 10 | 11 | def vars 12 | @vars ||= to_vars(:config, env_vars) 13 | end 14 | 15 | private 16 | 17 | def env_vars 18 | vars = Array(config[:global_env]) + Array(config[:env]) 19 | vars = vars.compact.reject(&:empty?) 20 | vars.flat_map { |var| Var.parse(var) } 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/travis/build/env/settings.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/env/base' 2 | 3 | module Travis 4 | module Build 5 | class Env 6 | class Settings < Base 7 | def source 8 | 'repository settings' 9 | end 10 | 11 | def vars 12 | @vars ||= to_vars(:settings, env_vars) 13 | end 14 | 15 | private 16 | 17 | def env_vars 18 | branch_specific, default = data.env_vars.partition { |v| v[:branch] == job[:branch]} 19 | 20 | (default + branch_specific).map do |var| 21 | if var[:branch].to_s.empty? || var[:branch] == job[:branch] 22 | [var[:name], var[:value], secure: !var[:public]] 23 | else 24 | nil 25 | end 26 | end.compact 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/travis/build/helpers.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/helpers/deprecation' 2 | require 'travis/build/helpers/template' 3 | -------------------------------------------------------------------------------- /lib/travis/build/helpers/deprecation.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Build 3 | module Deprecation 4 | class << self 5 | def deprecations 6 | @deprecations ||= [] 7 | end 8 | end 9 | 10 | def deprecations 11 | Deprecation.deprecations 12 | end 13 | 14 | def deprecate(msg) 15 | deprecations << msg unless deprecations.include?(msg) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/travis/build/helpers/template.rb: -------------------------------------------------------------------------------- 1 | require 'ostruct' 2 | 3 | module Travis 4 | module Build 5 | module Template 6 | class Template < OpenStruct 7 | def render(name, basedir: nil) 8 | name = name.to_s 9 | name = File.expand_path(name, basedir) unless basedir.nil? 10 | ERB.new(File.read(name)).result(binding) 11 | end 12 | end 13 | 14 | def template(name, vars = {}) 15 | Template.new(vars).render(name, basedir: self.class::TEMPLATES_PATH) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/travis/build/script/c.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Build 3 | class Script 4 | class C < Script 5 | DEFAULTS = { 6 | default: { compiler: 'gcc' }, 7 | freebsd: { compiler: 'cc' }, 8 | } 9 | 10 | def export 11 | super 12 | sh.export 'TRAVIS_COMPILER', compiler 13 | sh.export 'CC', "${CC:-#{compiler}}" 14 | sh.export 'CC_FOR_BUILD', "${CC_FOR_BUILD:-#{compiler}}" 15 | if data.cache?(:ccache) 16 | sh.export 'PATH', "/usr/lib/ccache:$PATH" 17 | end 18 | end 19 | 20 | def announce 21 | super 22 | sh.cmd "#{compiler} --version" 23 | end 24 | 25 | def script 26 | sh.cmd './configure && make && make test' 27 | end 28 | 29 | def cache_slug 30 | super << '--compiler-' << compiler 31 | end 32 | 33 | def setup_cache 34 | if data.cache?(:ccache) 35 | sh.fold 'cache.ccache' do 36 | sh.newline 37 | directory_cache.add('~/.ccache') 38 | end 39 | end 40 | end 41 | 42 | def use_directory_cache? 43 | super || data.cache?(:ccache) 44 | end 45 | 46 | private 47 | 48 | def compiler 49 | config[:compiler].to_s 50 | end 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/travis/build/script/generic.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Build 3 | class Script 4 | class Generic < Script 5 | DEFAULTS = {} 6 | 7 | def announce 8 | sh.cmd "bash -c 'echo $BASH_VERSION'", echo: true, assert: true, timing: false 9 | sh.newline 10 | end 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/travis/build/script/groovy.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/script/shared/jvm' 2 | 3 | module Travis 4 | module Build 5 | class Script 6 | class Groovy < Jvm 7 | DEFAULTS = {} 8 | # this builder completely inherits all the logic from the Jvm one. MK. 9 | end 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /lib/travis/build/script/node_js/manager.rb: -------------------------------------------------------------------------------- 1 | require_relative 'manager/base' 2 | require_relative 'manager/nvm' 3 | require_relative 'manager/nvs' 4 | 5 | module Travis 6 | module Build 7 | class NodeJs 8 | class Manager 9 | def self.nvm(node_js) 10 | Manager::Nvm.new(node_js) 11 | end 12 | 13 | def self.nvs(node_js) 14 | Manager::Nvs.new(node_js) 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/travis/build/script/node_js/manager/base.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | module Travis 4 | module Build 5 | class NodeJs 6 | class Manager 7 | class Base 8 | attr_reader :node_js 9 | 10 | extend Forwardable 11 | def_delegators :node_js, 12 | :sh, :config, :version, :app_host, :default_version, :node_js_given_in_config? 13 | 14 | def initialize(node_js) 15 | @node_js = node_js 16 | end 17 | 18 | def name 19 | self.class.to_s.sub(/.*::/,'').downcase 20 | end 21 | 22 | def setup 23 | end 24 | 25 | def update 26 | end 27 | 28 | def install 29 | end 30 | 31 | def show_version 32 | end 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/travis/build/script/node_js/manager/nvs.rb: -------------------------------------------------------------------------------- 1 | require_relative 'base' 2 | module Travis 3 | module Build 4 | class NodeJs 5 | class Manager 6 | class Nvs < Base 7 | def initialize(node_js) 8 | super 9 | 10 | end 11 | 12 | def setup 13 | 14 | end 15 | 16 | def update 17 | 18 | end 19 | 20 | def install 21 | install_version version 22 | use_version version 23 | end 24 | 25 | def show_version 26 | sh.cmd 'nvs --version' 27 | end 28 | 29 | def install_version(version) 30 | sh.cmd "nvs add #{version}" 31 | end 32 | 33 | def use_version(version) 34 | sh.cmd "nvs use #{version}" 35 | end 36 | end 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/travis/build/script/pure_java.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/script/shared/jvm' 2 | 3 | module Travis 4 | module Build 5 | class Script 6 | # JRuby makes "Java" a reserved word so we cannot name our subclass like that 7 | class PureJava < Jvm 8 | DEFAULTS = {} 9 | # this builder completely inherits all the logic from the Jvm one. MK. 10 | end 11 | end 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /lib/travis/build/script/ruby.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/script/shared/bundler' 2 | require 'travis/build/script/shared/jdk' 3 | require 'travis/build/script/shared/rvm' 4 | 5 | module Travis 6 | module Build 7 | class Script 8 | class Ruby < Script 9 | DEFAULTS = { 10 | rvm: 'default', 11 | gemfile: 'Gemfile' 12 | } 13 | 14 | include Bundler, RVM, Jdk 15 | 16 | def announce 17 | sh.fold 'ruby.versions' do 18 | super 19 | sh.cmd 'gem --version' 20 | end 21 | sh.newline 22 | end 23 | 24 | def script 25 | sh.if "-f #{config[:gemfile]}" do 26 | sh.cmd 'bundle exec rake' 27 | end 28 | sh.else do 29 | sh.cmd 'rake' 30 | end 31 | end 32 | 33 | private 34 | 35 | def uses_java? 36 | ruby_version.include?('jruby') 37 | end 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/travis/build/script/shared/chruby.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Build 3 | class Script 4 | module Chruby 5 | def setup 6 | super 7 | setup_chruby if chruby? 8 | end 9 | 10 | def announce 11 | super 12 | sh.cmd 'chruby --version' if chruby? 13 | end 14 | 15 | def cache_slug 16 | super.tap { |slug| slug << "--rvm-" << config[:ruby].to_s if chruby? } 17 | end 18 | 19 | private 20 | 21 | def chruby? 22 | !!config[:ruby] 23 | end 24 | 25 | def setup_chruby 26 | sh.echo 'BETA: Using chruby to select Ruby version. This is currently a beta feature and may change at any time.', ansi: :yellow 27 | sh.cmd 'curl -sLo ~/chruby.sh https://gist.githubusercontent.com/sarahhodne/a01cd7367b12a59ee051/raw/chruby.sh', echo: false 28 | sh.cmd 'source ~/chruby.sh', echo: false 29 | sh.cmd "chruby #{config[:ruby]}", timing: true 30 | end 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/travis/build/script/shared/directory_cache/gcs.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | require 'travis/build/script/shared/directory_cache/base' 4 | require 'travis/build/script/shared/directory_cache/signatures/aws2_signature' 5 | 6 | require 'uri' 7 | 8 | module Travis 9 | module Build 10 | class Script 11 | module DirectoryCache 12 | class Gcs < Base 13 | ACCESS_ID_PARAM_NAME = 'GoogleAccessId' 14 | 15 | def host_proc 16 | Proc.new do |region| 17 | 'storage.googleapis.com' 18 | end 19 | end 20 | end 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/travis/build/script/shared/directory_cache/noop.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Build 3 | class Script 4 | module DirectoryCache 5 | class Noop 6 | DATA_STORE = nil 7 | SIGNATURE_VERSION = nil 8 | 9 | EMPTY_BASH_METHODS = %i[ 10 | fetch 11 | push 12 | add 13 | ] 14 | 15 | attr_reader :sh 16 | 17 | def initialize(sh, *args) 18 | @sh = sh 19 | end 20 | 21 | def method_missing(method, *args) 22 | if EMPTY_BASH_METHODS.include? method 23 | sh.raw ':' 24 | else 25 | self 26 | end 27 | end 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/travis/build/script/shared/directory_cache/s3.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | require 'travis/build/script/shared/directory_cache/base' 4 | require 'travis/build/script/shared/directory_cache/signatures/aws4_signature' 5 | 6 | module Travis 7 | module Build 8 | class Script 9 | module DirectoryCache 10 | class S3 < Base 11 | def host_proc 12 | Proc.new do |region| 13 | case region 14 | when 'us-east-1' 15 | 's3.amazonaws.com' 16 | else 17 | "s3-#{region}.amazonaws.com" 18 | end 19 | end 20 | end 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/travis/build/stages/addon.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/stages/base' 2 | 3 | module Travis 4 | module Build 5 | class Stages 6 | class Addon < Base 7 | def run 8 | with_stage(name) { script.addons.run_stage(name) } if run? 9 | end 10 | 11 | def run? 12 | script.respond_to?(:addons) 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/travis/build/stages/base.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | module Travis 4 | module Build 5 | class Stages 6 | class Base < Struct.new(:script, :name) 7 | extend Forwardable 8 | 9 | def_delegators :script, :sh, :data, :config 10 | 11 | def with_stage(name = nil, &block) 12 | @stage = name 13 | options = STAGE_DEFAULT_OPTIONS[name] || {} 14 | 15 | sh.with_options(options || {}, &block) 16 | end 17 | 18 | def run_addon_stage(name) 19 | Addon.new(script, name).run 20 | end 21 | 22 | def result 23 | sh.raw 'travis_result $?' 24 | end 25 | 26 | def script? 27 | name == :script 28 | end 29 | 30 | def deployment? 31 | name == :after_success && config[:addons].is_a?(Hash) && !!config[:addons][:deploy] 32 | end 33 | 34 | def sbom? 35 | config[:addons].is_a?(Hash) && !!config[:addons][:sbom] 36 | end 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/travis/build/stages/builtin.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/stages/base' 2 | 3 | module Travis 4 | module Build 5 | class Stages 6 | class Builtin < Base 7 | def run 8 | with_stage(name) do 9 | run_addon_stage :"before_#{name}" 10 | run_addon_stage :script if script? # TODO for coverity_scan 11 | if script.respond_to?(name, true) 12 | script.send(name) 13 | result if script? 14 | end 15 | run_addon_stage :"after_#{name}" 16 | end 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/travis/build/stages/conditional.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/stages/base' 2 | 3 | module Travis 4 | module Build 5 | class Stages 6 | class Conditional < Base 7 | def run 8 | return unless config[name] || deployment? || sbom? 9 | 10 | result = Custom.new(script, name).run 11 | unless result.empty? 12 | sh.if(condition) do 13 | result 14 | end 15 | end 16 | end 17 | 18 | private 19 | 20 | def condition 21 | "$TRAVIS_TEST_RESULT #{operator} 0" 22 | end 23 | 24 | def operator 25 | name == :after_success ? '=' : '!=' 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/travis/build/stages/custom.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/stages/base' 2 | 3 | module Travis 4 | module Build 5 | class Stages 6 | class Custom < Base 7 | def run 8 | with_stage(name) do 9 | run_addon_stage :"before_#{name}" 10 | run_addon_stage :script if script? # TODO for coverity_scan 11 | cmds = Array(config[name]) 12 | cmds.each_with_index do |command, ix| 13 | sh.cmd command.to_s, echo: true, fold: fold_for(name, cmds, ix) 14 | result if script? 15 | end 16 | run_addon_stage :"after_#{name}" 17 | end 18 | end 19 | 20 | private 21 | 22 | def fold_for(stage, cmds, ix) 23 | "#{stage}#{".#{ix + 1}" if cmds.size > 1}" if fold_stage?(stage) 24 | end 25 | 26 | def fold_stage?(stage) 27 | stage != :script 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/travis/build/stages/skip.rb: -------------------------------------------------------------------------------- 1 | require 'travis/build/stages/base' 2 | 3 | module Travis 4 | module Build 5 | class Stages 6 | class Skip < Base 7 | def run 8 | sh.echo "Skipping the #{name} step, as specified in the configuration." 9 | sh.raw 'travis_result 0' if script? 10 | end 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/travis/services/vault.rb: -------------------------------------------------------------------------------- 1 | require 'travis/services/vault/keys' 2 | require 'travis/services/vault/connect' 3 | 4 | module Travis 5 | module Vault 6 | class ConnectionError < StandardError; end 7 | class RootKeyError < StandardError; end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/travis/services/vault/connect.rb: -------------------------------------------------------------------------------- 1 | require 'rest-client' 2 | 3 | module Travis 4 | module Vault 5 | class Connect 6 | def self.call(vault) 7 | response = RestClient.get("#{vault[:api_url]}/v1/auth/token/lookup-self", 'X-Vault-Token': vault[:token]) 8 | raise ConnectionError if response.code != 200 9 | rescue RestClient::ExceptionWithResponse, SocketError 10 | raise ConnectionError 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/travis/services/vault/keys.rb: -------------------------------------------------------------------------------- 1 | require 'travis/services/vault/keys/kv1' 2 | require 'travis/services/vault/keys/kv2' 3 | 4 | require 'travis/services/vault/keys/paths' 5 | require 'travis/services/vault/keys/version' 6 | require 'travis/services/vault/keys/resolver' 7 | 8 | module Travis 9 | module Vault 10 | class Keys 11 | 12 | attr_reader :appliance 13 | 14 | def initialize(appliance) 15 | @appliance = appliance 16 | end 17 | 18 | def resolve 19 | paths = Paths.call(appliance.vault) 20 | version = Version.call(appliance.vault) 21 | Resolver.new(paths, version, appliance).call 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/travis/services/vault/keys/build_paths.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vault 3 | class Keys 4 | class BuildPaths 5 | 6 | attr_reader :secrets 7 | 8 | def initialize(secrets) 9 | @secrets = secrets 10 | end 11 | 12 | def call 13 | secrets.map { |secret| format_paths(secret) } 14 | .flatten 15 | .reverse 16 | .uniq 17 | .reverse 18 | end 19 | 20 | private 21 | 22 | def format_paths(secret) 23 | return secret if secret.is_a?(String) 24 | return [] if secret[:namespace].blank? 25 | 26 | namespace_name = secret[:namespace].find { |el| el.try(:dig, :name) }&.dig(:name) 27 | 28 | return secret[:namespace] if namespace_name.blank? 29 | 30 | paths = secret[:namespace].reject { |el| el.is_a?(Hash) && el[:name] } 31 | paths.map { |path| "#{namespace_name}/#{path}" } 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/travis/services/vault/keys/kv1.rb: -------------------------------------------------------------------------------- 1 | require 'rest-client' 2 | 3 | module Travis 4 | module Vault 5 | class Keys 6 | class KV1 7 | def self.resolve(namespace, mount, path, vault) 8 | response = RestClient.get("#{vault[:api_url]}/v1/#{mount}/#{path}", 'X-Vault-Token': vault[:token], 'X-Vault-Namespace': namespace ? namespace : "") 9 | JSON.parse(response.body)['data'] if response.code == 200 10 | rescue RestClient::ExceptionWithResponse, SocketError 11 | nil 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/travis/services/vault/keys/kv2.rb: -------------------------------------------------------------------------------- 1 | require 'rest-client' 2 | 3 | module Travis 4 | module Vault 5 | class Keys 6 | class KV2 7 | def self.resolve(namespace, mount, path, vault) 8 | response = RestClient.get("#{vault[:api_url]}/v1/#{mount}/data/#{path}", 'X-Vault-Token': vault[:token], 'X-Vault-Namespace': namespace ? namespace : "") 9 | JSON.parse(response.body).dig('data', 'data') if response.code == 200 10 | rescue RestClient::ExceptionWithResponse, SocketError 11 | nil 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/travis/services/vault/keys/paths.rb: -------------------------------------------------------------------------------- 1 | require 'travis/services/vault/keys/build_paths' 2 | 3 | module Travis 4 | module Vault 5 | class Keys 6 | class Paths 7 | def self.call(vault) 8 | paths = vault[:secrets].reject { |secret| secret.is_a?(Hash) && secret[:kv_api_ver] } 9 | 10 | BuildPaths.new(paths).call 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/travis/services/vault/keys/version.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vault 3 | class Keys 4 | class Version 5 | DEFAULT_VALUE = 'kv2'.freeze 6 | 7 | def self.call(vault) 8 | vault[:secrets].find { |secret| secret.is_a?(Hash) && secret[:kv_api_ver] }&.values&.first || DEFAULT_VALUE 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/travis/shell.rb: -------------------------------------------------------------------------------- 1 | require 'travis/shell/ast' 2 | require 'travis/shell/builder' 3 | require 'travis/shell/generator' 4 | require 'travis/shell/generator/bash' 5 | 6 | module Travis 7 | module Shell 8 | class << self 9 | def generate(nodes) 10 | Generator::Bash.new(nodes).generate 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/travis/shell/generator/bash/cmd.rb: -------------------------------------------------------------------------------- 1 | require 'travis/shell/generator/bash/helpers' 2 | 3 | module Travis 4 | module Shell 5 | class Generator 6 | class Bash 7 | class Cmd 8 | include Helpers 9 | 10 | attr_reader :code, :options 11 | 12 | def initialize(code, options) 13 | @code = code 14 | @options = options 15 | end 16 | 17 | def to_bash 18 | cmd = ['travis_cmd'] 19 | cmd << escape(add_sudo(code)) 20 | cmd << opts(options) unless opts(options).empty? 21 | cmd.join(' ') 22 | end 23 | 24 | private 25 | 26 | def add_sudo(code) 27 | options[:sudo] ? "sudo #{code}" : code 28 | end 29 | 30 | def opts(options) 31 | opts ||= [] 32 | opts << '--assert' if options[:assert] 33 | opts << '--echo' if options[:echo] 34 | opts << "--display #{escape(options[:echo])}" if options[:echo].is_a?(String) 35 | opts << '--retry' if options[:retry] 36 | opts << '--timing' if options[:timing] 37 | opts << "--event #{options[:event].to_s}" if !options[:event].to_s.empty? 38 | opts << '--secure' if options[:secure] 39 | opts.join(' ') 40 | end 41 | end 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/travis/shell/generator/bash/helpers.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | require 'coder' 3 | 4 | module Travis 5 | module Shell 6 | class Generator 7 | class Bash 8 | module Helpers 9 | ANSI = { 10 | green: '\033[32;1m', 11 | red: '\033[31;1m', 12 | yellow: '\033[33;1m', 13 | reset: '\033[0m' 14 | } 15 | 16 | def ansi(string, keys) 17 | keys = Array(keys) 18 | prefix = keys.map { |key| ANSI[key] }.join 19 | suffix = ANSI[:reset] if keys.any? 20 | 21 | lines = string.split("\n").map do |line| 22 | line.strip.empty? ? line : [prefix, line, suffix].compact.flatten.join 23 | end 24 | lines.join("\n") 25 | end 26 | 27 | def escape(code) 28 | Shellwords.escape(Coder.force_encoding(code.to_s)) 29 | end 30 | end 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/travis/support/redis_pool.rb: -------------------------------------------------------------------------------- 1 | require 'connection_pool' 2 | require 'redis' 3 | 4 | module Travis 5 | class RedisPool 6 | attr_reader :pool 7 | 8 | def initialize(options = {}) 9 | pool_options = options.delete(:pool) || {} 10 | pool_options[:size] ||= 10 11 | pool_options[:timeout] ||= 10 12 | @pool = ConnectionPool.new(pool_options) do 13 | ::Redis.new(options) 14 | end 15 | end 16 | 17 | def method_missing(name, *args, &block) 18 | @pool.with do |redis| 19 | if redis.respond_to?(name) 20 | redis.send(name, *args, &block) 21 | else 22 | super 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/travis/vcs/base.rb: -------------------------------------------------------------------------------- 1 | #frozen_string_literal: true 2 | module Travis 3 | module Vcs 4 | class Base 5 | attr_reader :sh, :data 6 | 7 | def self.top 8 | raise NotImplementedError 9 | end 10 | 11 | def self.version 12 | raise NotImplementedError 13 | end 14 | 15 | def self.paths 16 | raise NotImplementedError 17 | end 18 | 19 | def self.defaults 20 | raise NotImplementedError 21 | end 22 | 23 | def initialize(sh, data) 24 | @sh = sh 25 | @data = data 26 | end 27 | 28 | def checkout 29 | raise NotImplementedError 30 | end 31 | 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/travis/vcs/git/netrc.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Git < Base 4 | class Netrc < Struct.new(:sh, :data) 5 | def apply 6 | sh.echo "Using ${TRAVIS_HOME}/#{netrc_filename} to clone repository." 7 | sh.raw "echo -e #{Shellwords.escape netrc_content} > ${TRAVIS_HOME}/#{netrc_filename}" 8 | sh.raw "chmod 0600 ${TRAVIS_HOME}/#{netrc_filename}" 9 | end 10 | 11 | def delete 12 | sh.raw "rm -f ${TRAVIS_HOME}/#{netrc_filename}" 13 | end 14 | 15 | private 16 | 17 | def netrc_content 18 | if data.installation? 19 | "machine #{data.source_host}\n login travis-ci\n password #{data.token}\n" 20 | else 21 | "machine #{data.source_host}\n login #{data.token}\n" 22 | end 23 | end 24 | 25 | def netrc_filename 26 | data.config[:os].to_s.downcase == 'windows' ? '_netrc' : '.netrc' 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/travis/vcs/git/ssh_key.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Git < Base 4 | class SshKey < Struct.new(:sh, :data) 5 | def apply 6 | sh.fold 'ssh_key' do 7 | sh.echo messages 8 | end 9 | 10 | sh.mkdir '~/.ssh', recursive: true, echo: false 11 | sh.file '~/.ssh/id_rsa', key.value 12 | sh.chmod 600, '~/.ssh/id_rsa', echo: false 13 | sh.raw 'eval `ssh-agent` &> /dev/null' 14 | sh.raw 'ssh-add ~/.ssh/id_rsa &> /dev/null' 15 | 16 | # BatchMode - If set to 'yes', passphrase/password querying will be disabled. 17 | # TODO ... how to solve StrictHostKeyChecking correctly? deploy a known_hosts file? 18 | sh.file '~/.ssh/config', "Host #{data.source_host}\n\tBatchMode yes\n\tStrictHostKeyChecking no\n", append: true 19 | end 20 | 21 | private 22 | 23 | def key 24 | data.ssh_key 25 | end 26 | 27 | def messages 28 | msgs = ["Installing SSH key#{" from: #{source}" if key.source}"] 29 | msgs << "Key fingerprint: #{key.fingerprint}" if key.fingerprint 30 | msgs 31 | end 32 | 33 | def source 34 | key.source.gsub(/[_-]+/, ' ') 35 | end 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/travis/vcs/git/submodules.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | module Travis 4 | module Vcs 5 | class Git < Base 6 | class Submodules < Struct.new(:sh, :data) 7 | def apply 8 | sh.if '-f .gitmodules' do 9 | sh.fold 'git.submodule' do 10 | sh.file '~/.ssh/config', "Host github.com\n\tStrictHostKeyChecking no\n", append: true 11 | sh.cmd "git submodule update --init --recursive --quiet #{update_args}".strip, assert: true, retry: true 12 | end 13 | end 14 | end 15 | 16 | private 17 | 18 | def update_args 19 | "--depth=#{depth}" if config[:git].key?(:submodules_depth) 20 | end 21 | 22 | def depth 23 | config[:git][:submodules_depth].to_s.shellescape 24 | end 25 | 26 | def config 27 | data.config 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/travis/vcs/git/tarball.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Git < Base 4 | class Tarball < Struct.new(:sh, :data) 5 | def apply 6 | sh.fold 'git.tarball' do 7 | mkdir 8 | download 9 | extract 10 | move 11 | end 12 | end 13 | 14 | private 15 | 16 | def mkdir 17 | sh.mkdir dir, echo: false, recursive: true 18 | end 19 | 20 | def download 21 | cmd = "curl -o #{filename} #{auth_header}-L #{tarball_url}" 22 | echo = cmd.gsub(data.token || /\Za/, '[SECURE]') 23 | sh.cmd cmd, echo: echo, retry: true 24 | end 25 | 26 | def extract 27 | sh.cmd "tar xfz #{filename}" 28 | end 29 | 30 | def move 31 | sh.mv "#{basename}-#{data.commit[0..6]}/*", dir, echo: false 32 | sh.cd dir 33 | end 34 | 35 | def dir 36 | data.slug 37 | end 38 | 39 | def filename 40 | "#{basename}.tar.gz" 41 | end 42 | 43 | def basename 44 | data.slug.gsub('/', '-') 45 | end 46 | 47 | def tarball_url 48 | "#{data.api_url}/tarball/#{data.commit}" 49 | end 50 | 51 | def auth_header 52 | "-H \"Authorization: token #{data.token}\" " if data.token 53 | end 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/travis/vcs/perforce/netrc.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Perforce < Base 4 | class Netrc < Struct.new(:sh, :data) 5 | def apply 6 | sh.echo "Using ${TRAVIS_HOME}/#{netrc_filename} to clone repository." 7 | sh.raw "echo -e #{Shellwords.escape netrc_content} > ${TRAVIS_HOME}/#{netrc_filename}" 8 | sh.raw "chmod 0600 ${TRAVIS_HOME}/#{netrc_filename}" 9 | end 10 | 11 | def delete 12 | sh.raw "rm -f ${TRAVIS_HOME}/#{netrc_filename}" 13 | end 14 | 15 | private 16 | 17 | def netrc_content 18 | if data.installation? 19 | "machine #{data.source_host}\n login travis-ci\n password #{data.token}\n" 20 | else 21 | "machine #{data.source_host}\n login #{data.token}\n" 22 | end 23 | end 24 | 25 | def netrc_filename 26 | data.config[:os].to_s.downcase == 'windows' ? '_netrc' : '.netrc' 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/travis/vcs/perforce/ssh_key.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Perforce < Base 4 | class SshKey < Struct.new(:sh, :data) 5 | def apply 6 | sh.fold 'ssh_key' do 7 | sh.echo messages 8 | end 9 | 10 | sh.mkdir '~/.ssh', recursive: true, echo: false 11 | sh.file '~/.ssh/id_rsa', key.value 12 | sh.chmod 600, '~/.ssh/id_rsa', echo: false 13 | sh.raw 'eval `ssh-agent` &> /dev/null' 14 | sh.raw 'ssh-add ~/.ssh/id_rsa &> /dev/null' 15 | 16 | # BatchMode - If set to 'yes', passphrase/password querying will be disabled. 17 | # TODO ... how to solve StrictHostKeyChecking correctly? deploy a known_hosts file? 18 | sh.file '~/.ssh/config', "Host #{data.source_host}\n\tBatchMode yes\n\tStrictHostKeyChecking no\n", append: true 19 | end 20 | 21 | private 22 | 23 | def key 24 | data.ssh_key 25 | end 26 | 27 | def messages 28 | msgs = ["Installing SSH key#{" from: #{source}" if key.source}"] 29 | msgs << "Key fingerprint: #{key.fingerprint}" if key.fingerprint 30 | msgs 31 | end 32 | 33 | def source 34 | key.source.gsub(/[_-]+/, ' ') 35 | end 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/travis/vcs/perforce/submodules.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | module Travis 4 | module Vcs 5 | class Perforce < Base 6 | class Submodules < Struct.new(:sh, :data) 7 | def apply 8 | end 9 | 10 | private 11 | 12 | def config 13 | data.config 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/travis/vcs/perforce/tarball.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Perforce < Base 4 | class Tarball < Struct.new(:sh, :data) 5 | def apply 6 | sh.fold 'p4.tarball' do 7 | mkdir 8 | download 9 | extract 10 | move 11 | end 12 | end 13 | 14 | private 15 | 16 | def mkdir 17 | sh.mkdir dir, echo: false, recursive: true 18 | end 19 | 20 | def download 21 | cmd = "curl -o #{filename} #{auth_header}-L #{tarball_url}" 22 | echo = cmd.gsub(data.token || /\Za/, '[SECURE]') 23 | sh.cmd cmd, echo: echo, retry: true 24 | end 25 | 26 | def extract 27 | sh.cmd "tar xfz #{filename}" 28 | end 29 | 30 | def move 31 | sh.mv "#{basename}-#{data.commit[0..6]}/*", dir, echo: false 32 | sh.cd dir 33 | end 34 | 35 | def dir 36 | data.slug 37 | end 38 | 39 | def filename 40 | "#{basename}.tar.gz" 41 | end 42 | 43 | def basename 44 | data.slug.gsub('/', '-') 45 | end 46 | 47 | def tarball_url 48 | "#{data.api_url}/tarball/#{data.commit}" 49 | end 50 | 51 | def auth_header 52 | "-H \"Authorization: token #{data.token}\" " if data.token 53 | end 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/travis/vcs/svn/netrc.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Svn < Base 4 | class Netrc < Struct.new(:sh, :data) 5 | def apply 6 | sh.echo "Using ${TRAVIS_HOME}/#{netrc_filename} to clone repository." 7 | sh.raw "echo -e #{Shellwords.escape netrc_content} > ${TRAVIS_HOME}/#{netrc_filename}" 8 | sh.raw "chmod 0600 ${TRAVIS_HOME}/#{netrc_filename}" 9 | end 10 | 11 | def delete 12 | sh.raw "rm -f ${TRAVIS_HOME}/#{netrc_filename}" 13 | end 14 | 15 | private 16 | 17 | def netrc_content 18 | if data.installation? 19 | "machine #{data.source_host}\n login travis-ci\n password #{data.token}\n" 20 | else 21 | "machine #{data.source_host}\n login #{data.token}\n" 22 | end 23 | end 24 | 25 | def netrc_filename 26 | data.config[:os].to_s.downcase == 'windows' ? '_netrc' : '.netrc' 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/travis/vcs/svn/submodules.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | module Travis 4 | module Vcs 5 | class Svn < Base 6 | class Submodules < Struct.new(:sh, :data) 7 | def apply 8 | end 9 | 10 | private 11 | 12 | def config 13 | data.config 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/travis/vcs/svn/tarball.rb: -------------------------------------------------------------------------------- 1 | module Travis 2 | module Vcs 3 | class Svn < Base 4 | class Tarball < Struct.new(:sh, :data) 5 | def apply 6 | sh.fold 'svn.tarball' do 7 | mkdir 8 | download 9 | extract 10 | move 11 | end 12 | end 13 | 14 | private 15 | 16 | def mkdir 17 | sh.mkdir dir, echo: false, recursive: true 18 | end 19 | 20 | def download 21 | cmd = "curl -o #{filename} #{auth_header}-L #{tarball_url}" 22 | echo = cmd.gsub(data.token || /\Za/, '[SECURE]') 23 | sh.cmd cmd, echo: echo, retry: true 24 | end 25 | 26 | def extract 27 | sh.cmd "tar xfz #{filename}" 28 | end 29 | 30 | def move 31 | sh.mv "#{basename}-#{data.commit[0..6]}/*", dir, echo: false 32 | sh.cd dir 33 | end 34 | 35 | def dir 36 | data.slug 37 | end 38 | 39 | def filename 40 | "#{basename}.tar.gz" 41 | end 42 | 43 | def basename 44 | data.slug.gsub('/', '-') 45 | end 46 | 47 | def tarball_url 48 | "#{data.api_url}/tarball/#{data.commit}" 49 | end 50 | 51 | def auth_header 52 | "-H \"Authorization: token #{data.token}\" " if data.token 53 | end 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /public/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/travis-ci/travis-build/bfcec65dffc6a0c2a9a1e883fc49dc7b9f0d5b7c/public/empty.txt -------------------------------------------------------------------------------- /public/version-aliases/README: -------------------------------------------------------------------------------- 1 | The files in this directory (other than this one) are *generated* and should not 2 | be directly altered. 3 | -------------------------------------------------------------------------------- /script/compile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | $LOAD_PATH.unshift File.expand_path('../lib', __dir__) 5 | require 'json' 6 | require 'travis/build' 7 | 8 | payload = JSON.parse(STDIN.read) 9 | puts Travis::Build.script(payload).compile 10 | -------------------------------------------------------------------------------- /script/docker-build-and-push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | app_name="web" 6 | local_image="travis-build-${app_name}" 7 | quay_image=quay.io/travisci/travis-build 8 | 9 | unset DOCKER_CERT_PATH 10 | unset DOCKER_HOST 11 | unset DOCKER_TLS 12 | unset DOCKER_TLS_VERIFY 13 | 14 | docker-compose build "${app_name}" 15 | docker login -u="${QUAY_ROBOT_HANDLE}" -p="${QUAY_ROBOT_TOKEN}" quay.io 16 | docker images 17 | 18 | docker tag "${local_image}" "${quay_image}:${TRAVIS_BRANCH}" 19 | docker push "${quay_image}:${TRAVIS_BRANCH}" 20 | 21 | docker tag "${local_image}" "${quay_image}:${TRAVIS_COMMIT:0:7}" 22 | docker push "${quay_image}:${TRAVIS_COMMIT:0:7}" 23 | 24 | if [[ "${TRAVIS_BRANCH}" == "master" ]]; then 25 | docker tag "${local_image}" "${quay_image}:latest" 26 | docker push "${quay_image}:latest" 27 | fi 28 | 29 | exit 0 30 | -------------------------------------------------------------------------------- /script/get-latest-go: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | require 'net/http' 4 | require 'json' 5 | 6 | def go_json 7 | res = Net::HTTP.get URI('https://go.dev/dl/?mode=json&include=all') 8 | j = JSON.parse(res) 9 | j.reverse_each do |x| 10 | next unless x['stable'] == true 11 | 12 | version = x['version'] 13 | version.slice!('go') 14 | parts = version.split('.') 15 | parts.pop if parts.length > 2 16 | fname = parts.join('.') 17 | 18 | File.write("/tmp/go-version-#{fname}.x", version) 19 | end 20 | end 21 | 22 | def go_version 23 | res = Net::HTTP.get URI('https://go.dev/dl/') 24 | start = res.index '/dl/go' 25 | if start 26 | start += '/dl/'.length 27 | last = res.index '"', start 28 | res[start, last- start]&.match(/go\d+\.\d+\.?\d*/)&.to_s[2..] 29 | end 30 | end 31 | 32 | File.write('/tmp/go-version',go_version) 33 | go_json 34 | -------------------------------------------------------------------------------- /script/handle-docker-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit 3 | 4 | main() { 5 | local top client_config_url 6 | top="$(git rev-parse --show-toplevel)" 7 | 8 | [[ "${DOCKER_CLIENT_CONFIG_URL}" ]] || { 9 | log "missing \${DOCKER_CLIENT_CONFIG_URL}" 10 | exit 0 11 | } 12 | 13 | client_config_url="$(base64 --decode <<<"${DOCKER_CLIENT_CONFIG_URL}")" 14 | 15 | local tmp_zip="${top}/tmp/docker-client-config.zip" 16 | mkdir -p "${top}/tmp" 17 | 18 | log 'fetching client config' 19 | curl -fsSL -o "${tmp_zip}" "${client_config_url}" >&2 20 | 21 | log "expanding ${tmp_zip}" 22 | unzip -d "${top}" "${tmp_zip}" >&2 23 | 24 | echo "export DOCKER_CERT_PATH='${top}/.docker';" 25 | echo "export DOCKER_TLS_VERIFY=1;" 26 | echo "export DOCKER_TLS=1;" 27 | } 28 | 29 | log() { 30 | printf "handle-docker-config: %s\\n" "${*}" >&2 31 | } 32 | 33 | main "${@}" 34 | -------------------------------------------------------------------------------- /script/healthcheck: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require 'net/http' 5 | require 'uri' 6 | Net::HTTP.get( 7 | URI("http://localhost:#{ENV.fetch('PORT', '4000')}/uptime") 8 | ) 9 | -------------------------------------------------------------------------------- /script/server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit 3 | 4 | main() { 5 | ./script/get-latest-go & 6 | cd "$(dirname "$0")/.." 7 | : "${PORT:=5000}" 8 | : "${RACK_ENV:=development}" 9 | 10 | local cmd=( 11 | bundle exec je puma -I lib 12 | -p "${PORT}" 13 | -t "${PUMA_MIN_THREADS:-8}:${PUMA_MAX_THREADS:-12}" 14 | -w "${PUMA_WORKERS:-2}" 15 | ) 16 | 17 | if [[ -f public.tar.bz2 && ! -d public ]]; then 18 | tar -xf public.tar.bz2 19 | fi 20 | 21 | if [[ -f BUILD_SLUG_COMMIT ]]; then 22 | export BUILD_SLUG_COMMIT 23 | BUILD_SLUG_COMMIT=$(cat ./BUILD_SLUG_COMMIT) 24 | fi 25 | 26 | if [[ "${RACK_ENV}" == development ]] && 27 | [[ ! -f /.dockerenv ]] && 28 | [[ ! "${DISABLE_RERUN}" ]]; then 29 | cmd=(bundle exec rerun -p '**/*.{rb,ru}' -- "${cmd[@]}") 30 | fi 31 | 32 | echo "----> ${cmd[*]}" 33 | exec "${cmd[@]}" 34 | } 35 | 36 | main "${@}" 37 | -------------------------------------------------------------------------------- /spec/build/addons/apt_retries_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Addons::AptRetries, :sexp do 4 | let(:script) { stub('script') } 5 | let(:data) { payload_for(:push, :ruby, config: { addons: { apt_retries: config } }) } 6 | let(:sh) { Travis::Shell::Builder.new } 7 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 8 | 9 | subject { sh.to_sexp } 10 | before { addon.before_configure } 11 | 12 | context "when apt_retries is set" do 13 | let(:config) { 'true' } 14 | 15 | it { store_example } 16 | it { should include_sexp [:echo, "Configuring default apt-get retries", ansi: :yellow] } 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/build/addons/blender_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Addons::Blender, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { '10.0' } 6 | let(:data) { payload_for(:push, :ruby, config: { addons: { blender: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.after_prepare } 11 | 12 | context 'when version is invalid' do 13 | let(:config) { '2.112323' } 14 | 15 | it do 16 | should include_sexp [:echo, "Blender: Invalid version '2.112323' given. Valid versions are: 3.4.1", { ansi: :red }] 17 | end 18 | end 19 | 20 | context 'when version is valid' do 21 | let(:config) { '3.4.1' } 22 | 23 | it { should include_sexp [:echo, 'Installing Blender version: 3.4.1', { ansi: :yellow }] } 24 | it { should include_sexp [:cmd, 'CURL_USER_AGENT="Travis-CI $(curl --version | head -n 1)"', { echo: true }] } 25 | xit { should include_sexp [:cmd, 'mkdir ${TRAVIS_HOME}/blender'], { echo: true } } 26 | it { should include_sexp [:cmd, 'curl -A "$CURL_USER_AGENT" -sSf -L --retry 7 https://ftp.halifax.rwth-aachen.de/blender/release/Blender3.4/blender-3.4.1-linux-x64.tar.xz | tar xf - -J -C ${TRAVIS_HOME}/blender --strip-components 1', { echo: true }] } 27 | it { should include_sexp [:cmd, 'PATH=$PATH:${TRAVIS_HOME}/blender', { echo: true }] } 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/build/addons/code_climate_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Addons::CodeClimate, :sexp do 4 | let(:script) { stub('script') } 5 | let(:data) { payload_for(:push, :ruby, config: { addons: { code_climate: config } }) } 6 | let(:config) { { repo_token: '1234' } } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.before_before_script } 11 | 12 | let(:export_repo_token) { [:export, ['CODECLIMATE_REPO_TOKEN', '1234']] } 13 | 14 | it_behaves_like 'compiled script' do 15 | let(:code) { ['CODECLIMATE_REPO_TOKEN=1234'] } 16 | end 17 | 18 | describe 'with a token' do 19 | it { should include_sexp export_repo_token } 20 | it { store_example } 21 | end 22 | 23 | describe 'without a token' do 24 | let(:config) { {} } 25 | it { should_not include_sexp export_repo_token } 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/build/addons/coverity_scan_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Addons::CoverityScan, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { {} } 6 | let(:data) { payload_for(:push, :ruby, config: { addons: { coverity_scan: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.script } 11 | 12 | # it_behaves_like 'compiled script' do 13 | # let(:code) { ['CODECLIMATE_REPO_TOKEN=1234'] } 14 | # end 15 | 16 | xit 'needs specs!' 17 | end 18 | -------------------------------------------------------------------------------- /spec/build/addons/hostname_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe Travis::Build::Addons::Hostname, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { 'newhostname' } 6 | let(:data) { payload_for(:push, :ruby, config: { addons: { hostname: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.after_prepare } 11 | 12 | it { store_example } 13 | 14 | it_behaves_like 'compiled script' do 15 | let(:cmds) { ['hostname'] } 16 | end 17 | 18 | it { should include_sexp [:cmd, "sudo hostname #{config}", echo: true] } 19 | end 20 | 21 | -------------------------------------------------------------------------------- /spec/build/addons/hosts_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe Travis::Build::Addons::Hosts, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { 'one.local two.local' } 6 | let(:data) { payload_for(:push, :ruby, config: { addons: { hosts: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.after_prepare } 11 | 12 | it { store_example } 13 | 14 | it_behaves_like 'compiled script' do 15 | let(:cmds) { ['one.local two.local'] } 16 | end 17 | 18 | # it { should include_sexp [:cmd, "sed -e 's/^\\(127\\.0\\.0\\.1.*\\)$/\\1 'one.local\\ two.local'/' -i'.bak' /etc/hosts", sudo: true] } 19 | # it { should include_sexp [:cmd, "sed -e 's/^\\(::1.*\\)$/\\1 'one.local\\ two.local'/' -i'.bak' /etc/hosts", sudo: true] } 20 | it { should include_sexp [:cmd, "sed -e 's/^\\(127\\.0\\.0\\.1.*\\)$/\\1 one.local\\ two.local/' /etc/hosts > /tmp/hosts"] } 21 | it { should include_sexp [:cmd, "cat /tmp/hosts | sudo tee /etc/hosts > /dev/null"] } 22 | end 23 | 24 | -------------------------------------------------------------------------------- /spec/build/addons/pkg_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe Travis::Build::Addons::Pkg, :sexp do 4 | let(:script) { stub('script') } 5 | #let(:pkg_config) { ['travis', { name: 'aws-cli', no_deps: true }] } 6 | let(:pkg_config) { {} } 7 | let(:data) { payload_for(:push, :ruby, config: { os: 'freebsd', addons: { pkg: pkg_config } }) } 8 | let(:sh) { Travis::Shell::Builder.new } 9 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), pkg_config) } 10 | subject { sh.to_sexp } 11 | before { addon.before_prepare } 12 | 13 | context 'when on linux' do 14 | let(:data) { payload_for(:push, :ruby, config: { os: 'linux' }) } 15 | 16 | it 'will not run' do 17 | expect(addon.before_prepare?).to eql false 18 | end 19 | end 20 | 21 | context 'when on freebsd' do 22 | let(:data) { payload_for(:push, :ruby, config: { os: 'freebsd' }) } 23 | 24 | it 'will run' do 25 | expect(addon.before_prepare?).to eql true 26 | end 27 | end 28 | 29 | context 'with multiple packages' do 30 | let(:pkg_config) { { packages: ['git', 'curl'] } } 31 | 32 | it { should include_sexp [:cmd, "su -m root -c 'pkg install git curl'", echo: true, timing: true, assert: true] } 33 | end 34 | 35 | context 'with single packages' do 36 | let(:pkg_config) { { packages: ['git'] } } 37 | 38 | it { should include_sexp [:cmd, "su -m root -c 'pkg install git'", echo: true, timing: true, assert: true] } 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/build/addons/postgresql_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Addons::Postgresql, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { '9.3' } 6 | let(:data) { payload_for(:push, :ruby, config: { addons: { postgresql: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | 11 | before do 12 | script.stubs(bash: '# (bash here)') 13 | addon.after_prepare 14 | end 15 | 16 | it { store_example } 17 | 18 | it_behaves_like 'compiled script' do 19 | let(:code) { [ 20 | 'service postgresql start ${version}', 21 | 'systemctl start postgresql@${version}-main', 22 | 'sudo -u postgres createuser -s -p "${port}" travis', 23 | 'sudo -u postgres createdb -O travis -p "${port}" travis', 24 | 'export PATH="/usr/lib/postgresql/${version}/bin:$PATH"', 25 | 'cp -rp \"/var/lib/postgresql/${version}\" \"/var/ramfs/postgresql/${version}\"' 26 | ] } 27 | end 28 | 29 | it { should include_sexp [:cmd, "travis_setup_postgresql #{config}", echo: true, timing: true] } 30 | end 31 | -------------------------------------------------------------------------------- /spec/build/addons/snaps_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe Travis::Build::Addons::Snaps, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { ['travis', { name: 'aws-cli', classic: true }] } 6 | let(:data) { payload_for(:push, :ruby, config: { dist: 'xenial', addons: { snaps: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.before_prepare } 11 | 12 | it { store_example } 13 | 14 | it_behaves_like 'compiled script' do 15 | let(:cmds) { ['sudo snap install travis'] } 16 | end 17 | 18 | it { should include_sexp [:cmd, "sudo snap install core", echo: true, timing: true, assert: true] } 19 | it { should include_sexp [:cmd, "sudo snap install travis", echo: true, timing: true, assert: true] } 20 | it { should include_sexp [:cmd, "sudo snap install aws-cli --classic", echo: true, timing: true, assert: true] } 21 | it { should include_sexp [:cmd, "sudo snap list", echo: true, timing: true, assert: true] } 22 | end 23 | -------------------------------------------------------------------------------- /spec/build/addons/srcclr_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Addons::Srcclr, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { {} } 6 | let(:data) { payload_for(:push, :ruby, config: { addons: { srcclr: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.before_finish } 11 | 12 | context 'given true config' do 13 | let(:config) { true } 14 | it { 15 | should include_sexp [:cmd, 'curl -sSL https://download.sourceclear.com/ci.sh | bash', {:echo=>true, :timing=>true}] 16 | } 17 | end 18 | 19 | context 'given true config' do 20 | let(:config) { { debug: true } } 21 | it { 22 | should include_sexp [:cmd, 'curl -sSL https://download.sourceclear.com/ci.sh | env DEBUG=1 bash', {:echo=>true, :timing=>true}] 23 | } 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /spec/build/addons/tensor_flow_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Addons::TensorFlow, :sexp do 4 | let(:script) { stub('script') } 5 | let(:config) { '10.0' } 6 | let(:data) { payload_for(:push, :ruby, config: { addons: { tensor_flow: config } }) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:addon) { described_class.new(script, sh, Travis::Build::Data.new(data), config) } 9 | subject { sh.to_sexp } 10 | before { addon.after_prepare } 11 | 12 | context 'when version is invalid' do 13 | let(:config) { '2.112323' } 14 | 15 | it do 16 | should include_sexp [:echo, "Invalid version '2.112323' given. Valid versions are: 0.12.1 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.6.0 1.7.0 1.7.1 1.8.0 1.9.0 1.10.0 1.10.1 1.11.0 1.12.0 1.12.2 1.12.3 1.13.1 1.13.2 1.14.0 1.15.0 1.15.2 1.15.31.15.4 1.15.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.5.2 2.6.0rc0 2.6.0rc1 2.6.0rc2 2.6.0 2.6.1 2.6.2", { ansi: :red }] end 17 | end 18 | 19 | context 'when version is valid' do 20 | let(:config) { '2.6.0' } 21 | 22 | it { should include_sexp [:echo, 'Installing TensorFlow version: 2.6.0', { ansi: :yellow }] } 23 | it { should include_sexp [:cmd, "pip install tensorflow==2.6.0"] } 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/build/appliances/docker_config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Appliances::DockerConfig, :sexp do 4 | let(:config) { PAYLOADS[:worker_config] } 5 | let(:payload) { payload_for(:push, :ruby, config: { addons: {}, cache: 'bundler'}).merge(config) } 6 | let(:script) { Travis::Build.script(payload) } 7 | let(:code) { script.compile } 8 | subject { script.sexp } 9 | 10 | describe '#apply' do 11 | context 'use default' do 12 | before {ENV.delete('TRAVIS_BUILD_DOCKER_BUILDKIT_PROGRESS') } 13 | it { should include_sexp [:raw, "export BUILDKIT_PROGRESS=plain"] } 14 | end 15 | 16 | context 'use custom' do 17 | before {ENV['TRAVIS_BUILD_DOCKER_BUILDKIT_PROGRESS'] = 'tty' } 18 | it { should include_sexp [:raw, "export BUILDKIT_PROGRESS=tty"] } 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/build/bash/travis_getaddrinfo_spec.rb: -------------------------------------------------------------------------------- 1 | describe 'travis_getaddrinfo', integration: true do 2 | include SpecHelpers::BashFunction 3 | 4 | it 'is valid bash' do 5 | expect(run_script('travis_getaddrinfo', '')[:truth]).to be true 6 | end 7 | 8 | it 'can run successfully' do 9 | result = run_script( 10 | 'travis_getaddrinfo', 11 | 'travis_getaddrinfo www.google.com', 12 | image: 'ruby:2.5.3', 13 | ) 14 | expect(result[:truth]).to be true 15 | response = result[:out].read.strip.split($NL).first 16 | expect(response).to_not be_nil 17 | expect(response).to_not be_empty 18 | expect(Addrinfo.tcp(response, 80).ip?).to be true 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/build/bash/travis_preamble_spec.rb: -------------------------------------------------------------------------------- 1 | describe 'travis_preamble', integration: true do 2 | include SpecHelpers::BashFunction 3 | 4 | it 'is valid bash' do 5 | expect(run_script('travis_preamble', '')[:truth]).to be true 6 | end 7 | 8 | it 'can run successfully' do 9 | expect(run_script('travis_preamble', 'travis_preamble')[:truth]).to be true 10 | end 11 | 12 | it 'appends sourcing of job stages to ~/.bashrc' do 13 | result = run_script( 14 | 'travis_preamble', 'travis_preamble && cat /home/travis/.bashrc' 15 | ) 16 | expect(result[:truth]).to be true 17 | expect(result[:out].read).to include 'source /home/travis/.travis/job_stages' 18 | end 19 | 20 | it 'creates and changes dirs to TRAVIS_BUILD_DIR' do 21 | result = run_script('travis_preamble', 'travis_preamble && pwd') 22 | expect(result[:truth]).to be true 23 | expect(result[:out].read.strip).to eq '/home/travis/build/travis_preamble_spec' 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/build/bash/travis_retry_spec.rb: -------------------------------------------------------------------------------- 1 | describe 'travis_retry', integration: true do 2 | include SpecHelpers::BashFunction 3 | 4 | it 'is valid bash' do 5 | expect(run_script('travis_retry', '')[:truth]).to be true 6 | end 7 | 8 | it 'returns immediately on success' do 9 | expect( 10 | run_script('travis_retry', 'travis_retry echo whatebber')[:truth] 11 | ).to be true 12 | end 13 | 14 | it 'reports retries' do 15 | res = run_script('travis_retry', 'travis_retry cat /non/existent/file') 16 | expect(res[:err].read).to include('Retrying, ') 17 | end 18 | 19 | it 'reports failure after 3 attempts' do 20 | res = run_script('travis_retry', 'travis_retry cat /non/existent/file') 21 | expect(res[:err].read).to include('failed 3 times.') 22 | end 23 | 24 | it 'returns the exit code of the process that is retried' do 25 | res = run_script('travis_retry', 'travis_retry some-nonexistent-command') 26 | expect(res[:exitstatus]).to eq 127 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/build/bash/travis_script_go_spec.rb: -------------------------------------------------------------------------------- 1 | describe 'travis_script_go', integration: true do 2 | include SpecHelpers::BashFunction 3 | 4 | let :script_header do 5 | <<~BASH 6 | apk add --no-cache grep 7 | 8 | travis_cmd() { 9 | TRAVIS_CMD_RAN+=("${*}") 10 | } 11 | TRAVIS_CMD_RAN=() 12 | 13 | source /tmp/tbb/travis_has_makefile.bash 14 | source /tmp/tbb/__travis_go_functions.bash 15 | 16 | export TRAVIS_BUILD_DIR=/var/tmp/build 17 | mkdir -p "${TRAVIS_BUILD_DIR}" 18 | BASH 19 | end 20 | 21 | it 'is valid bash' do 22 | expect(run_script('travis_script_go', '')[:truth]).to be true 23 | end 24 | 25 | it 'runs make when a makefile is present' do 26 | result = run_script( 27 | 'travis_script_go', 28 | <<~BASH 29 | #{script_header} 30 | 31 | touch ${TRAVIS_BUILD_DIR}/Makefile 32 | 33 | travis_script_go -v 34 | 35 | echo "${TRAVIS_CMD_RAN[@]}" 36 | BASH 37 | ) 38 | 39 | expect(result[:err].read.strip).to eq '' 40 | expect(result[:out].read).to match(/\bmake\b/) 41 | end 42 | 43 | it 'runs "go test" when makefile is not present' do 44 | result = run_script( 45 | 'travis_script_go', 46 | <<~BASH 47 | #{script_header} 48 | 49 | travis_script_go -v 50 | 51 | echo "${TRAVIS_CMD_RAN[@]}" 52 | BASH 53 | ) 54 | 55 | expect(result[:err].read.strip).to eq '' 56 | expect(result[:out].read).to match(/\bgo test -v \.\/\.\.\./) 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/build/bash/travis_setup_go_spec.rb: -------------------------------------------------------------------------------- 1 | describe 'travis_setup_go', integration: true do 2 | include SpecHelpers::BashFunction 3 | 4 | let(:go_version) { '1.22.5' } 5 | let(:go_import_path) { 'github.com/travis-ci-examples/go-example' } 6 | 7 | let :script_header do 8 | <<~BASH 9 | apk add --no-cache grep sudo 10 | 11 | travis_cmd() { 12 | TRAVIS_CMD_RAN+=("${*}") 13 | } 14 | TRAVIS_CMD_RAN=() 15 | 16 | source /tmp/tbb/travis_has_makefile.bash 17 | source /tmp/tbb/__travis_go_functions.bash 18 | 19 | export TRAVIS_BUILD_DIR=/var/tmp/build 20 | mkdir -p "${TRAVIS_BUILD_DIR}" 21 | BASH 22 | end 23 | 24 | it 'is valid bash' do 25 | expect(run_script('travis_setup_go', '')[:truth]).to be true 26 | end 27 | 28 | it 'requires TRAVIS_GO_VERSION' do 29 | result = run_script( 30 | 'travis_setup_go', 31 | <<~BASH 32 | #{script_header} 33 | 'travis_setup_go' 34 | BASH 35 | ) 36 | expect(result[:err].read.strip). 37 | to include('Missing TRAVIS_GO_VERSION') 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /spec/build/bash/travis_temporary_hacks_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helpers/bash_function' 2 | 3 | describe 'travis_temporary_hacks', integration: true do 4 | include SpecHelpers::BashFunction 5 | 6 | it 'is valid bash' do 7 | expect(run_script('travis_temporary_hacks', '')[:truth]).to be true 8 | end 9 | 10 | %w[ 11 | linux 12 | osx 13 | windows 14 | notset 15 | ].each do |os_name| 16 | it "can run successfully on os=#{os_name}" do 17 | expect( 18 | run_script( 19 | 'travis_temporary_hacks', 20 | "TRAVIS_OS_NAME=#{os_name} travis_temporary_hacks" 21 | )[:truth] 22 | ).to be true 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/build/bash/travis_whereami_spec.rb: -------------------------------------------------------------------------------- 1 | describe 'travis_whereami', integration: true do 2 | include SpecHelpers::BashFunction 3 | 4 | it 'is valid bash' do 5 | expect(run_script('travis_whereami', '')[:truth]).to be true 6 | end 7 | 8 | it 'can run successfully' do 9 | result = run_script( 10 | 'travis_whereami', 11 | 'apk add --no-cache curl &>/dev/null && travis_whereami' 12 | ) 13 | 14 | expect(result[:truth]).to be true 15 | 16 | outlines = result[:out].read.lines.map(&:strip) 17 | expect(outlines.first).to match(/^infra=.+/) 18 | expect(outlines.last).to match(/^ip=.+/) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/build/config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Config do 4 | subject { Travis::Build.config } 5 | 6 | it 'defines #ghc_version_aliases_hash' do 7 | expect(subject.ghc_version_aliases_hash).to_not be_empty 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/build/git/submodules_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Vcs::Git::Clone, :sexp do 4 | let(:payload) { payload_for(:push, :ruby) } 5 | let(:script) { Travis::Build::Script.new(payload) } 6 | subject { script.sexp } 7 | 8 | let(:sexp) { sexp_find(subject, [:if, '-f .gitmodules'], [:then]) } 9 | 10 | let(:no_host_key_check) { [:file, ['~/.ssh/config', "Host github.com\n\tStrictHostKeyChecking no\n"], append: true] } 11 | let(:submodule_update) { [:cmd, 'git submodule update --init --recursive --quiet', assert: true, echo: true, retry: true, timing: true] } 12 | 13 | describe 'if .gitmodules exists' do 14 | it { should include_sexp no_host_key_check } 15 | 16 | describe 'if :submodules_depth is not given' do 17 | it { should include_sexp submodule_update } 18 | end 19 | 20 | describe 'if :submodules_depth is given' do 21 | before { payload[:config][:git] = { submodules_depth: 50 } } 22 | it { should include_sexp [:cmd, 'git submodule update --init --recursive --quiet --depth=50', assert: true, echo: true, retry: true, timing: true] } 23 | end 24 | end 25 | 26 | describe 'submodules is set to false' do 27 | before { payload[:config][:git] = { submodules: false } } 28 | 29 | it { expect(sexp_find(subject, submodule_update)).to be_empty } 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/build/script/groovy_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Script::Groovy, :sexp do 4 | let(:data) { payload_for(:push, :groovy) } 5 | let(:script) { described_class.new(data) } 6 | subject { script.sexp } 7 | it { store_example } 8 | 9 | it_behaves_like 'a bash script' 10 | 11 | it_behaves_like 'compiled script' do 12 | let(:code) { ['TRAVIS_LANGUAGE=groovy'] } 13 | let(:cmds) { ['gradlew check'] } 14 | end 15 | 16 | it_behaves_like 'a build script sexp' 17 | it_behaves_like 'a jvm build sexp' 18 | it_behaves_like 'announces java versions' 19 | end 20 | 21 | -------------------------------------------------------------------------------- /spec/build/script/haxe_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Script::Haxe, :sexp do 4 | let(:data) { payload_for(:push, :haxe) } 5 | let(:script) { described_class.new(data) } 6 | subject { script.sexp } 7 | it { store_example } 8 | 9 | it_behaves_like 'a bash script' 10 | it_behaves_like 'a build script sexp' 11 | 12 | it 'downloads and installs haxe' do 13 | should include_sexp [:cmd, %r(curl .*haxe.*\.tar\.gz), 14 | assert: true, echo: true, timing: true] 15 | end 16 | 17 | it 'downloads and installs neko' do 18 | should include_sexp [:cmd, %r(curl .*neko.*\.tar\.gz), 19 | assert: true, echo: true, timing: true] 20 | end 21 | 22 | it 'announces haxe -version' do 23 | should include_sexp [:cmd, /haxe -version/, assert: true, echo: true] 24 | end 25 | 26 | it 'announces neko -version' do 27 | should include_sexp [:cmd, /neko -version/, assert: true, echo: true] 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/build/script/julia_spec.rb: -------------------------------------------------------------------------------- 1 | # vim:set ts=2 sw=2 sts=2 autoindent: 2 | 3 | require 'spec_helper' 4 | 5 | describe Travis::Build::Script::Julia, :sexp do 6 | let(:data) { payload_for(:push, :julia) } 7 | let(:script) { described_class.new(data) } 8 | subject { script.sexp } 9 | it { store_example } 10 | 11 | it_behaves_like 'a bash script' 12 | it_behaves_like 'a build script sexp' 13 | 14 | it 'sets TRAVIS_JULIA_VERSION' do 15 | should include_sexp [:export, ['TRAVIS_JULIA_VERSION', '1']] 16 | end 17 | 18 | it 'downloads and installs Julia' do 19 | should include_sexp [:cmd, %r(curl .*latest-linux-x86_64), assert: true, 20 | echo: true, timing: true] 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /spec/build/script/nix_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Script::Nix, :sexp do 4 | let(:data) { payload_for(:push, :nix) } 5 | let(:script) { described_class.new(data) } 6 | subject { script.sexp } 7 | it { store_example } 8 | 9 | it_behaves_like 'a bash script' 10 | 11 | it 'announces nix-env --version' do 12 | should include_sexp [:cmd, 'nix-env --version', echo: true] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/build/script/perl6_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Script::Perl6, :sexp do 4 | let(:data) { payload_for(:push, :perl6) } 5 | let(:script) { described_class.new(data) } 6 | subject { script.sexp } 7 | it { store_example } 8 | 9 | it_behaves_like 'a bash script' 10 | 11 | it_behaves_like 'compiled script' do 12 | let(:code) { ['TRAVIS_LANGUAGE=perl6'] } 13 | end 14 | 15 | it_behaves_like 'a build script sexp' 16 | 17 | it 'announces perl6 --version' do 18 | should include_sexp [:cmd, 'perl6 --version', echo: true] 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /spec/build/script/pure_java_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build::Script::PureJava, :sexp do 4 | let(:data) { payload_for(:push, :java) } 5 | let(:script) { described_class.new(data) } 6 | subject { script.sexp } 7 | it { store_example } 8 | 9 | it_behaves_like 'a bash script' 10 | 11 | it_behaves_like 'compiled script' do 12 | let(:code) { ['TRAVIS_LANGUAGE=java'] } 13 | let(:cmds) { ['gradlew check'] } 14 | end 15 | 16 | it_behaves_like 'a build script sexp' 17 | it_behaves_like 'a jvm build sexp' 18 | it_behaves_like 'announces java versions' 19 | end 20 | 21 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/check_unsupported.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'checks language support' do 2 | it "terminates early on windows" do 3 | sexp = sexp_find(subject, [:if, '"$TRAVIS_OS_NAME" = windows']) 4 | expect(sexp).to include_sexp([:raw, 'travis_terminate 1']) 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/clean_up_path.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'cleans up $PATH' do 2 | 3 | it 'removes empty path from $PATH' do 4 | should include_sexp [ :export, ['PATH', "$(echo $PATH | sed -e 's/::/:/g')" ] ] 5 | end 6 | 7 | it 'removes duplicates from $PATH' do 8 | should include_sexp [ :export, ['PATH', "$(echo -n $PATH | perl -e 'print join(\":\", grep { not $seen{$_}++ } split(/:/, scalar <>))')" ] ] 9 | end 10 | end -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/disable_initramfs.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'disables updating initramfs' do 2 | let(:disable_initramfs) { %(if [ ! $(uname|egrep 'Darwin|FreeBSD') ]; then echo update_initramfs=no | sudo tee -a /etc/initramfs-tools/update-initramfs.conf > /dev/null; fi) } 3 | 4 | it 'disables updating initramfs' do 5 | should include_sexp [:raw, disable_initramfs] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/disable_ssh_roaming.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'disables OpenSSH roaming' do 2 | let(:sexp) { sexp_find(subject, [:if, %("$(sw_vers -productVersion 2>/dev/null | cut -d . -f 2)" -lt 12)]) } 3 | 4 | it 'disables OpenSSH roaming' do 5 | expect(sexp).to include_sexp [:cmd, 'travis_disable_ssh_roaming'] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/disable_sudo.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'paranoid mode on/off' do 2 | it 'does not remove access to sudo by default' do 3 | should_not include_sexp [:cmd, 'travis_disable_sudo'] 4 | end 5 | 6 | it 'removes access to sudo if enabled in the config' do 7 | data[:paranoid] = true 8 | should include_sexp [:cmd, 'travis_disable_sudo'] 9 | store_example(name: 'disable sudo') if data[:config][:language] == :ruby 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/disable_windows_defender.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'disables Windows Defender' do 2 | context 'on non-Windows' do 3 | it { should_not include_sexp [:raw, 'powershell -Command Set-MpPreference -DisableArchiveScanning \\$true'] } 4 | end 5 | 6 | context 'on Windows' do 7 | before :each do 8 | data[:config][:os] = 'windows' 9 | end 10 | 11 | it 'disables Windows Defender' do 12 | should include_sexp [:cmd, 'powershell -Command Set-MpPreference -DisableArchiveScanning \\$true', echo: true] 13 | should include_sexp [:cmd, 'powershell -Command Set-MpPreference -DisableRealtimeMonitoring \\$true', echo: true] 14 | should include_sexp [:cmd, 'powershell -Command Set-MpPreference -DisableBehaviorMonitoring \\$true', echo: true] 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/etc_hosts_pinning.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for '/etc/hosts pinning' do 2 | before do 3 | Travis::Build.config.etc_hosts_pinning = '127.0.0.1 foo,0.0.0.0 bar' 4 | end 5 | 6 | after do 7 | Travis::Build.config.etc_hosts_pinning = '' 8 | end 9 | 10 | it 'writes to /etc/hosts' do 11 | should include_sexp [:raw, 'echo 127.0.0.1\\ foo | sudo tee -a /etc/hosts &>/dev/null'] 12 | should include_sexp [:raw, 'echo 0.0.0.0\\ bar | sudo tee -a /etc/hosts &>/dev/null'] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/fix_etc_hosts.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'fix etc/hosts' do 2 | let(:fix_etc_hosts) { "sudo sed -e 's/^\\(127\\.0\\.0\\.1.*\\)$/\\1 '`hostname`'/' -i'.bak' /etc/hosts 2> /dev/null" } 3 | 4 | it 'adds an entry to /etc/hosts for localhost' do 5 | should include_sexp [:raw, fix_etc_hosts] 6 | end 7 | 8 | it 'skips adding an entry to /etc/hosts for localhost' do 9 | data[:skip_etc_hosts_fix] = true 10 | should_not include_sexp [:raw, fix_etc_hosts] 11 | end 12 | 13 | it 'skips adding an entry to /etc/hosts for localhost if fix_etc_hosts=false' do 14 | data[:fix_etc_hosts] = false 15 | should_not include_sexp [:raw, fix_etc_hosts] 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/fix_etc_mavenrc.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'fix etc/mavenrc' do 2 | let(:fix_etc_mavenrc) { "test -f /etc/mavenrc && sudo sed -e 's/M2_HOME=\\(.\\+\\)$/M2_HOME=${M2_HOME:-\\1}/' -i'.bak' /etc/mavenrc" } 3 | 4 | it 'adds an sexp to fix /etc/mavenrc' do 5 | should include_sexp [:raw, fix_etc_mavenrc] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/fix_mvn_settings_xml.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'fix ~/.m2/settings.xml' do 2 | it 'updates ~/.m2/settings.xml' do 3 | should include_sexp [:cmd, "sed -i$([ \"$TRAVIS_OS_NAME\" == osx ] && echo \" \").bak1 -e 's|https://nexus.codehaus.org/snapshots/|https://oss.sonatype.org/content/repositories/codehaus-snapshots/|g' ~/.m2/settings.xml"] 4 | should include_sexp [:cmd, "sed -i$([ \"$TRAVIS_OS_NAME\" == osx ] && echo \" \").bak2 -e 's|https://repository.apache.org/releases/|https://repository.apache.org/content/repositories/releases/|g' ~/.m2/settings.xml"] 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/fix_ps4.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'fix ps4' do 2 | it 'sets PS4 to fix an rvm issue' do 3 | should include_sexp [:export, ['PS4', '+']] 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/fix_resolv_conf.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'fix resolve.conf' do 2 | let(:resolv_conf_data) { <<-EOF } 3 | options rotate 4 | options timeout:1 5 | 6 | nameserver 8.8.8.8 7 | nameserver 8.8.4.4 8 | nameserver 208.67.222.222 9 | nameserver 208.67.220.220 10 | EOF 11 | let(:fix_resolv_conf) { "echo \"#{resolv_conf_data}\" | sudo tee /etc/resolv.conf &> /dev/null" } 12 | 13 | it 'fixes the DNS entries in /etc/resolv.conf' do 14 | should include_sexp [:raw, fix_resolv_conf] 15 | end 16 | 17 | it 'skips fixing the DNS entries in /etc/resolv.conf if told to' do 18 | data[:skip_resolv_updates] = true 19 | should_not include_sexp [:raw, fix_resolv_conf] 20 | end 21 | 22 | it 'skips fixing the DNS entries in /etc/resolv.conf if fix_resolv_conf=false' do 23 | data[:fix_resolv_conf] = false 24 | should_not include_sexp [:raw, fix_resolv_conf] 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/fix_sudo_enabled_trusty.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'fix sudo-enabled trusty' do 2 | it 'unsets _JAVA_OPTIONS' do 3 | should include_sexp [:cmd, 'unset _JAVA_OPTIONS'] 4 | end 5 | 6 | it 'unsets MALLOC_ARENA_MAX' do 7 | should include_sexp [:cmd, 'unset MALLOC_ARENA_MAX'] 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/no_ipv6_localhost.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'removes IPv6 addresses from /etc/hosts' do 2 | let(:no_ipv6_localhost) { "sudo sed -e 's/^\\([0-9a-f:]\\+\\) localhost/\\1/' -i'.bak' /etc/hosts" } 3 | 4 | it 'removes localhost from IPv6 addresses in /etc/hosts' do 5 | should include_sexp [:raw, no_ipv6_localhost] 6 | end 7 | 8 | context "when sudo is unavailable" do 9 | before { data[:paranoid] = true } 10 | it 'does not remove localhost from IPv6 addresses in /etc/hosts' do 11 | should_not include_sexp [:raw, no_ipv6_localhost] 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/npm_registry.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'npm registry override' do 2 | it 'sets the NPM_CONFIG_REGISTRY env var' do 3 | data[:npm_registry] = 'npm-cache.travisci.net' 4 | should include_sexp [:export, ['NPM_CONFIG_REGISTRY', 'npm-cache.travisci.net'], echo: true] 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/put_localhost_first.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'put localhost first in etc/hosts' do 2 | let(:put_localhost_first) { %q(grep '^127\.0\.0\.1' /etc/hosts | sed -e 's/^127\.0\.0\.1\\s\\{1,\\}\\(.*\\)/\1/g' | sed -e 's/localhost \\(.*\\)/\1/g' | tr "\n" " " > /tmp/hosts_127_0_0_1) } 3 | 4 | it 'places localhost first in /etc/hosts' do 5 | should include_sexp [:raw, put_localhost_first] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/rm_etc_boto_cfg.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'remove /etc/boto.cfg' do 2 | let(:rm_etc_boto_cfg) { "rm -f /etc/boto.cfg" } 3 | 4 | it "removes /etc/boto.cfg" do 5 | should include_sexp [:cmd, rm_etc_boto_cfg, sudo: true] 6 | end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/rvm_use.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'rvm use' do 2 | let(:sexp) { sexp_filter(subject, [:if, '$(command -v sw_vers)']) } 3 | it 'runs "rvm use"' do 4 | expect(sexp).to include_sexp [:cmd, "rvm use &>/dev/null"] 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/setup_filter.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'setup filter' do 2 | let(:filter) {[:echo, 'Secret environment variables are not obfuscated on Windows, please refer to our documentation: https://docs.travis-ci.com/user/best-practices-security', ansi: 'yellow']} 3 | 4 | describe 'skips on Windows' do 5 | before do 6 | data[:config][:os] = 'windows' 7 | end 8 | 9 | describe 'skips secrets filtering' do 10 | it {should include_sexp filter} 11 | end 12 | end 13 | 14 | describe 'runs on Linux' do 15 | before do 16 | data[:config][:os] = 'linux' 17 | end 18 | 19 | describe 'skips secrets filtering' do 20 | it {should_not include_sexp filter} 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/stages.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'build script stages' do 2 | def assert_stage?(stage) 3 | %w(before_install install before_script).include?(stage) 4 | end 5 | 6 | %w(before_install install before_script script after_script after_success).each do |stage| 7 | before :each do 8 | data[:config][stage] = ["#{stage}.1.sh", "#{stage}.2.sh"] 9 | end 10 | 11 | 1.upto(2) do |num| 12 | it "runs the given :#{stage} script #{stage}.#{num}.sh" do 13 | options = { echo: true, timing: true } 14 | options[:assert] = true if assert_stage?(stage) 15 | should include_sexp [:cmd, "#{stage}.#{num}.sh", options] 16 | end 17 | end 18 | 19 | next if stage == 'script' 20 | 21 | 1.upto(2) do |num| 22 | it "adds a fold marker for the :#{stage} script #{num}" do 23 | expect(sexp_find(subject, [:fold, "#{stage}.#{num}"])).to_not be_empty 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/uninstall_oclint.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'uninstalls oclint' do 2 | it 'runs "brew cask uninstall oclint"' do 3 | should include_sexp [:cmd, 'brew cask uninstall oclint &>/dev/null'] 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/update_apt_keys.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'update expired apt keys' do 2 | it 'updates expired apt keys' do 3 | should include_sexp [:cmd, 'apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv', echo: false, assert: false, sudo: true] 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/update_glibc.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'update libc6' do 2 | let(:command) { [:echo, 'Forcing update of libc6', ansi: :yellow] } 3 | 4 | context "when update_glibc is unset" do 5 | it 'updates libc6' do 6 | should_not include_sexp(command) 7 | end 8 | end 9 | 10 | context "when sudo is enabled" do 11 | before :each do 12 | data[:paranoid] = false 13 | end 14 | 15 | it 'updates libc6' do 16 | should_not include_sexp(command) 17 | end 18 | end 19 | 20 | context "when update_glibc is unset" do 21 | let(:sexp) { sexp_find(subject, [:if, '${TRAVIS_OS_NAME} == linux && ${TRAVIS_DIST} == precise']) } 22 | 23 | before :each do 24 | Travis::Build.config.update_glibc = '1' 25 | data[:paranoid] = true 26 | end 27 | 28 | it 'updates libc6' do 29 | should include_sexp(command) 30 | end 31 | 32 | after :each do 33 | Travis::Build.config.update_glibc = '' 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/update_libssl.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'update libssl1.0.0' do 2 | let(:update_libssl) { "apt-get install ca-certificates libssl1.0.0" } 3 | 4 | context "when sudo is available" do 5 | it "does not update libssl1.0.0" do 6 | should_not include_sexp [:cmd, update_libssl, sudo: true, echo: true] 7 | end 8 | end 9 | context "when sudo is unavailable" do 10 | before :each do 11 | data[:paranoid] = true 12 | end 13 | 14 | context "on Precise" do 15 | let(:sexp) { sexp_find(subject, [:if, "-n $(command -v lsb_release) && $(lsb_release -cs) = 'precise'"]) } 16 | 17 | it 'updates libssl1.0.0' do 18 | expect(sexp).to include_sexp [:cmd, update_libssl, sudo: true, echo: true] 19 | end 20 | end 21 | 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/build/script/shared/appliances/validate.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'validates config' do 2 | let(:fetch_error) { [:echo, 'Could not fetch .travis.yml from GitHub.', ansi: :red] } 3 | let(:missing_config) { [:echo, 'Could not find .travis.yml, using standard configuration.', ansi: :red] } 4 | let(:terminate) { [:raw, 'travis_terminate 2'] } 5 | let(:run_script) { [:cmd, './the_script', echo: true, timing: true] } 6 | 7 | before do 8 | data[:config][:'.result'] = result 9 | data[:config][:script] = './the_script' 10 | end 11 | 12 | describe 'server error' do 13 | let(:result) { 'server_error' } 14 | it { should include_sexp fetch_error } 15 | it { should include_sexp terminate } 16 | it { should_not include_sexp run_script } 17 | it { store_example(name: 'config server error') if data[:config][:language] == :ruby } 18 | end 19 | 20 | describe 'not found' do 21 | let(:result) { 'not_found' } 22 | it { should include_sexp missing_config } 23 | it { should_not include_sexp terminate } 24 | it { should include_sexp run_script } 25 | it { store_example(name: 'config not found') if data[:config][:language] == :ruby } 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/build/services/vault/connect_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Vault::Connect do 4 | describe '#call' do 5 | subject(:call) { described_class.call(vault) } 6 | 7 | let(:vault) do 8 | { 9 | api_url: 'https://myvault.org', 10 | token: 'my-token' 11 | } 12 | end 13 | 14 | context 'the endpoint returns 200' do 15 | before do 16 | stub_request(:get, 'https://myvault.org/v1/auth/token/lookup-self'). 17 | with(headers: { 'X-Vault-Token': 'my-token' }). 18 | to_return(status: 200) 19 | end 20 | 21 | it { expect { call }.not_to raise_error } 22 | end 23 | 24 | context 'the endpoint returns not-200' do 25 | before do 26 | stub_request(:get, 'https://myvault.org/v1/auth/token/lookup-self'). 27 | with(headers: { 'X-Vault-Token': 'my-token' }). 28 | to_return(status: 403) 29 | end 30 | 31 | it { expect { call }.to raise_error(Travis::Vault::ConnectionError) } 32 | end 33 | 34 | context 'the endpoint is not correctly defined' do 35 | let(:vault) do 36 | { 37 | api_url: '!https://myvault.org', 38 | token: 'my-token' 39 | } 40 | end 41 | 42 | it { expect { call }.to raise_error(Travis::Vault::ConnectionError) } 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/build/services/vault/keys/kv1_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Vault::Keys::KV1 do 4 | describe '.resolve' do 5 | subject { described_class.resolve('', 'secret', path, vault) } 6 | 7 | let(:vault) do 8 | { 9 | api_url: 'https://myvault.org', 10 | token: 'my-token' 11 | } 12 | end 13 | 14 | let(:path) { 'path/to/variable' } 15 | 16 | context 'when the response code is 200' do 17 | before do 18 | stub_request(:get, 'https://myvault.org/v1/secret/path/to/variable'). 19 | with(headers: { 'X-Vault-Token': 'my-token' }). 20 | to_return(status: 200, body: { data: { my_data: { b: '123' } } }.to_json) 21 | end 22 | 23 | it do 24 | is_expected.to eq({ 'my_data' => { 'b' => '123' } }) 25 | end 26 | end 27 | 28 | context 'when the response code is not 200' do 29 | before do 30 | stub_request(:get, 'https://myvault.org/v1/secret/path/to/variable'). 31 | with(headers: { 'X-Vault-Token': 'my-token' }). 32 | to_return(status: 404, body: '') 33 | end 34 | 35 | it 'does not explode' do 36 | is_expected.to be_nil 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/build/services/vault/keys/kv2_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Vault::Keys::KV2 do 4 | describe '.resolve' do 5 | subject { described_class.resolve('', 'secret', path, vault) } 6 | 7 | let(:vault) do 8 | { 9 | api_url: 'https://myvault.org', 10 | token: 'my-token' 11 | } 12 | end 13 | 14 | let(:path) { 'path/to/variable' } 15 | 16 | context 'when the response code is 200' do 17 | before do 18 | stub_request(:get, 'https://myvault.org/v1/secret/data/path/to/variable'). 19 | with(headers: { 'X-Vault-Token': 'my-token' }). 20 | to_return(status: 200, body: { data: { data: { my_data: { a: '123' } } } }.to_json) 21 | end 22 | 23 | it do 24 | is_expected.to eq({ 'my_data' => { 'a' => '123' } }) 25 | end 26 | end 27 | 28 | context 'when the response code is not 200' do 29 | before do 30 | stub_request(:get, 'https://myvault.org/v1/secret/data/path/to/variable'). 31 | with(headers: { 'X-Vault-Token': 'my-token' }). 32 | to_return(status: 404, body: '') 33 | end 34 | 35 | it 'does not explode' do 36 | is_expected.to be_nil 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/build/services/vault/keys/paths_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Vault::Keys::Paths do 4 | describe '.call' do 5 | subject(:call) { described_class.call(vault) } 6 | 7 | let(:build_paths) { stub(call: nil) } 8 | 9 | let(:vault) do 10 | { secrets: 11 | [ 12 | 'aaa/bbb', 13 | 'ccc', 14 | { kv_api_ver: 'kv1' }, 15 | 'whatever/else/here' 16 | ] 17 | } 18 | end 19 | 20 | it 'passes to BuildPaths initializer everything but not a hash with kv_api_key' do 21 | Travis::Vault::Keys::BuildPaths.expects(:new).with(%w[aaa/bbb ccc whatever/else/here]).returns(build_paths) 22 | build_paths.expects(:call) 23 | 24 | call 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/build/services/vault/keys/version_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Vault::Keys::Version do 4 | describe '.call' do 5 | subject(:call) { described_class.call(vault) } 6 | 7 | context 'when kv_api_ver key is there' do 8 | let(:vault) do 9 | { 10 | secrets: [ 11 | 'aaa/bbb', 12 | 'ccc', 13 | { kv_api_ver: 'kv1' }, 14 | 'whatever/else/here' 15 | ] 16 | } 17 | end 18 | 19 | it 'uses its value' do 20 | is_expected.to eq('kv1') 21 | end 22 | end 23 | 24 | context 'when kv_api_ver is not there' do 25 | let(:vault) do 26 | { 27 | secrets: %w[aaa/bbb ccc whatever/else/here] 28 | } 29 | end 30 | 31 | it 'uses default value' do 32 | is_expected.to eq('kv2') 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/build/services/vault/keys_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Vault::Keys do 4 | describe '#resolve' do 5 | subject(:resolve) { described_class.new(appliance).resolve } 6 | 7 | let(:vault) { { api_url: 'https://my_vault.com', token: 'my_token' } } 8 | let(:appliance) { stub(vault: vault) } 9 | 10 | let(:paths) { stub(:paths) } 11 | let(:version) { stub(:version) } 12 | let(:resolver) { stub(call: nil) } 13 | 14 | it 'calls Resolver with proper parameters' do 15 | Travis::Vault::Keys::Version.expects(:call).with(vault).returns(version) 16 | Travis::Vault::Keys::Paths.expects(:call).with(vault).returns(paths) 17 | 18 | Travis::Vault::Keys::Resolver.expects(:new).with(paths, version, appliance).returns(resolver) 19 | resolver.expects(:call) 20 | 21 | resolve 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/build/vcs/perforce_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Travis::Vcs::Perforce, :sexp do 6 | let(:data) { payload_for(:perforce, :ruby, config: {}) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:perforce) { described_class.new(sh, Travis::Build::Data.new(data)) } 9 | 10 | describe '#checkout' do 11 | subject { sh.to_sexp } 12 | 13 | before { perforce.checkout } 14 | 15 | it { is_expected.to include_sexp([:export, ['P4USER', 'pubkey'], echo: true]) } 16 | it { is_expected.to include_sexp([:export, ['P4CHARSET', 'utf8']]) } 17 | it { is_expected.to include_sexp([:export, ['P4PORT', 'ssl:perforce.assembla.com']]) } 18 | it { is_expected.to include_sexp([:cmd, 'p4 trust -y']) } 19 | it { is_expected.to include_sexp([:cmd, "echo $(p4 info | grep 'Server address:' | cut -d ' ' -f 3- 2>/dev/null)=pubkey:privatekey > /tmp/p4ticket"]) } 20 | it { is_expected.to include_sexp([:export, ['P4TICKETS', '/tmp/p4ticket']]) } 21 | it { is_expected.to include_sexp([:cmd, 'p4 -v ssl.client.trust.name=1 client -S //depot/main -o | p4 -v ssl.client.trust.name=1 client -i']) } 22 | it { is_expected.to include_sexp([:cmd, 'p4 -v ssl.client.trust.name=1 sync -p']) } 23 | it { is_expected.to include_sexp([:cd, 'tempdir', echo: true]) } 24 | it { is_expected.not_to include_sexp([:mkdir, '~/.ssh', recursive: true]) } 25 | end 26 | end -------------------------------------------------------------------------------- /spec/build/vcs/svn/clone_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Travis::Vcs::Svn::Clone, :sexp do 6 | let(:data) { payload_for(payload_name, :ruby, config: {}) } 7 | let(:sh) { Travis::Shell::Builder.new } 8 | let(:clone) { described_class.new(sh, Travis::Build::Data.new(data)) } 9 | 10 | describe '#apply' do 11 | let(:assembla_checkout_sexp) { [:cmd, 'svn co svn+ssh://assembla.com/branches/main ruby-example', retry: true] } 12 | let(:update_sexp) { [:cmd, 'svn update -r 9500504'] } 13 | let(:payload_name) { :svn } 14 | 15 | subject { sh.to_sexp } 16 | 17 | before { clone.apply } 18 | 19 | it { is_expected.to include_sexp(assembla_checkout_sexp) } 20 | it { is_expected.to include_sexp(update_sexp) } 21 | 22 | context 'when repository is not from Assembla' do 23 | let(:payload_name) { :svn_non_assembla } 24 | 25 | it { is_expected.to include_sexp([:cmd, 'svn co /branches/main ruby-example', retry: true]) } 26 | it { is_expected.to include_sexp(update_sexp) } 27 | end 28 | 29 | context 'when the job is a PR' do 30 | let(:payload_name) { :svn_pull_request } 31 | 32 | it { is_expected.to include_sexp(assembla_checkout_sexp) } 33 | it { is_expected.not_to include(update_sexp) } 34 | it { is_expected.to include_sexp([:cmd, 'svn merge --non-interactive ^/branches/newfeature']) } 35 | end 36 | end 37 | end -------------------------------------------------------------------------------- /spec/build/vcs_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Travis::Vcs do 6 | describe '#defaults' do 7 | subject { described_class.defaults(server_type) } 8 | 9 | context 'when server_type is subversion' do 10 | let(:server_type) { 'subversion' } 11 | 12 | it 'returns svn defaults' do 13 | expect(subject).to eq(Travis::Vcs::Svn::DEFAULTS) 14 | end 15 | end 16 | 17 | context 'when server_type is git' do 18 | let(:server_type) { 'git' } 19 | 20 | it 'returns svn defaults' do 21 | expect(subject).to eq(Travis::Vcs::Git::DEFAULTS) 22 | end 23 | end 24 | end 25 | end -------------------------------------------------------------------------------- /spec/build_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Build do 4 | describe '.by_lang' do 5 | 6 | { 7 | Android: ['android'], 8 | C: ['c'], 9 | Clojure: ['clojure'], 10 | Cpp: ['cpp', 'c++', 'cplusplus'], 11 | Crystal: ['crystal'], 12 | Csharp: ['csharp'], 13 | D: ['d'], 14 | Dart: ['dart'], 15 | Erlang: ['erlang'], 16 | Generic: ['generic', 'bash', 'sh', 'shell', 'minimal'], 17 | Go: ['go'], 18 | Groovy: ['groovy'], 19 | Haskell: ['haskell'], 20 | Haxe: ['haxe'], 21 | Julia: ['julia'], 22 | Nix: ['nix'], 23 | NodeJs: ['node_js'], 24 | ObjectiveC: ['objective_c', 'objective-c', 'swift'], 25 | Perl6: ['perl6'], 26 | Perl: ['perl'], 27 | Php: ['php'], 28 | PureJava: ['java', 'java-anything'], 29 | Python: ['python'], 30 | R: ['r'], 31 | Ruby: ['ruby'], 32 | Rust: ['rust'], 33 | Scala: ['scala'], 34 | Smalltalk: ['smalltalk'], 35 | }.each do |script_type, langs| 36 | langs.each do |lang| 37 | it "returns #{script_type} for #{lang}" do 38 | expect(described_class.by_lang(lang)).to eq(Travis::Build::Script.const_get(script_type)) 39 | end 40 | end 41 | end 42 | 43 | it 'returns Ruby for unknown languages' do 44 | expect(described_class.by_lang('foo')).to eq(Travis::Build::Script::Ruby) 45 | end 46 | 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/filter_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'timeout' 3 | 4 | require_relative '../public/filter/redirect_io' 5 | 6 | describe Filter do 7 | let(:cmd) { File.expand_path('../../public/filter/redirect_io.rb', __FILE__) } 8 | def filter(input, *secrets) 9 | args = secrets.map { |s| "-s #{Shellwords.escape(s)}" }.join " " 10 | input = Shellwords.escape(input) 11 | `echo #{input} | ruby #{cmd} #{args}`.chomp 12 | end 13 | 14 | describe 'simple replacements' do 15 | example { expect(filter('foobar', 'baz')).to be == 'foobar' } 16 | example { expect(filter('foobar foobaz', 'foobar', 'baz')).to be == '[secure] foo[secure]' } 17 | example { expect(filter('foobar foobaz', 'foobar', 'foo')).to be == '[secure] [secure]baz' } 18 | example { expect(filter('foobar foobaz', 'foo', 'foobar')).to be == '[secure] [secure]baz' } 19 | example { expect(filter('abcdef', 'a', 'bc', 'def')).to be == 'abc[secure]' } 20 | end 21 | 22 | it 'live streams' do 23 | code = %( 24 | print 'foo' 25 | sleep 0.01 26 | print 'bar' 27 | sleep 0.01 28 | print 'baz' 29 | sleep 0.01 30 | ) 31 | output = `ruby -e "#{code}" | ruby #{cmd} -s bar` 32 | expect(output).to be == 'foo[secure]baz' 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/shell/generator/bash/cmd_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Travis::Shell::Generator::Bash::Cmd, :include_node_helpers do 4 | let(:args) { ['cd ..', @options || {}] } 5 | let(:subject) { Travis::Shell::Generator::Bash::Cmd.new(*args).to_bash } 6 | 7 | it 'prefixes with `travis_cmd` and escapes the code' do 8 | should eql('travis_cmd cd\ ..') 9 | end 10 | 11 | it 'adds sudo if :sudo is given' do 12 | @options = { sudo: true } 13 | should eql('travis_cmd sudo\ cd\ ..') 14 | end 15 | 16 | it 'adds --assert if :assert is given' do 17 | @options = { assert: true } 18 | should eql('travis_cmd cd\ .. --assert') 19 | end 20 | 21 | it 'adds --echo if :echo is given' do 22 | @options = { echo: true } 23 | should eql('travis_cmd cd\ .. --echo') 24 | end 25 | 26 | it 'adds both --echo and --display if :echo is a String' do 27 | @options = { echo: 'display' } 28 | should eql('travis_cmd cd\ .. --echo --display display') 29 | end 30 | 31 | it 'adds --retry if :retry is given' do 32 | @options = { retry: true } 33 | should eql('travis_cmd cd\ .. --retry') 34 | end 35 | 36 | it 'adds --timing if :timing is given' do 37 | @options = { timing: true } 38 | should eql('travis_cmd cd\ .. --timing') 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['ENV'] = 'test' 2 | 3 | require 'simplecov' 4 | require 'fileutils' 5 | require 'sinatra/test_helpers' 6 | require 'travis/build' 7 | require 'pathname' 8 | require 'webmock/rspec' 9 | 10 | WebMock.allow_net_connect! 11 | 12 | Dir["{spec/spec_helpers,spec/support,spec/**/shared}/**/*.rb"].each do |f| 13 | load(f) 14 | end 15 | 16 | module SpecHelpers 17 | def top 18 | @top ||= Pathname.new(`git rev-parse --show-toplevel`.strip) 19 | end 20 | 21 | module_function :top 22 | 23 | def integration? 24 | ENV['INTEGRATION_SPECS'] == '1' 25 | end 26 | 27 | module_function :integration? 28 | end 29 | 30 | RSpec.configure do |c| 31 | c.include SpecHelpers::Logger 32 | c.include SpecHelpers::Payload 33 | c.include SpecHelpers::Node, :include_node_helpers 34 | c.include SpecHelpers::Sexp, :sexp 35 | c.include SpecHelpers::Shell, :script 36 | c.include Sinatra::TestHelpers, :include_sinatra_helpers 37 | 38 | c.mock_with :mocha 39 | 40 | c.filter_run_excluding(integration: true) unless SpecHelpers.integration? 41 | c.filter_run_excluding(example: true) 42 | end 43 | -------------------------------------------------------------------------------- /spec/spec_helpers/bash_function.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | module SpecHelpers 4 | module BashFunction 5 | def run_script(function_name, command, image: 'bash:4', out: nil, 6 | err: nil, cleanup: true) 7 | container_name = "travis_bash_function_#{rand(1000..1999)}" 8 | 9 | out ||= Tempfile.new('travis_bash_function') 10 | err ||= Tempfile.new('travis_bash_function') 11 | 12 | script = "source /tmp/tbb/#{function_name}.bash; #{command}" 13 | 14 | system( 15 | %W[ 16 | docker create 17 | #{cleanup ? '--rm' : ''} 18 | -e TRAVIS_ROOT=/ 19 | -e TRAVIS_HOME=/home/travis 20 | -e TRAVIS_BUILD_DIR=/home/travis/build/#{function_name}_spec 21 | --name=#{container_name} 22 | #{image} 23 | bash -c 24 | ].join(' ') + ' ' + Shellwords.escape(script), 25 | %i[out err] => '/dev/null' 26 | ) 27 | 28 | system( 29 | "docker cp #{bash_dir} #{container_name}:/tmp/tbb", 30 | %i[out err] => '/dev/null' 31 | ) 32 | 33 | truth = system( 34 | "docker start -i -a #{container_name}", 35 | out: out.fileno, err: err.fileno 36 | ) 37 | 38 | [out, err].each do |stream| 39 | stream.rewind if stream.respond_to?(:rewind) 40 | end 41 | 42 | { 43 | exitstatus: $?.exitstatus, 44 | truth: truth, 45 | out: out, 46 | err: err 47 | } 48 | end 49 | 50 | private def bash_dir 51 | @bash_dir ||= SpecHelpers.top.join('lib/travis/build/bash') 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /spec/spec_helpers/node.rb: -------------------------------------------------------------------------------- 1 | module SpecHelpers 2 | module Node 3 | def create_node(type, *args) 4 | case type 5 | when :cmd, :file, :echo 6 | Travis::Shell::Ast::Cmd.new(type, *args) 7 | else 8 | const = type.to_s.sub(/^(.)/) { $1.upcase } 9 | Travis::Shell::Ast.const_get(const).new(*args) 10 | end 11 | end 12 | 13 | def add_elif(node, condition, cmds) 14 | branch = create_node(:elif, condition) 15 | node.branches << branch 16 | cmds.each { |cmd| branch.nodes << create_node(:cmd, cmd) } 17 | branch 18 | end 19 | 20 | def add_else(node, cmds) 21 | branch = create_node(:else) 22 | node.branches << branch 23 | cmds.each { |cmd| branch.nodes << create_node(:cmd, cmd) } 24 | branch 25 | end 26 | end 27 | end 28 | 29 | -------------------------------------------------------------------------------- /spec/spec_helpers/payload.rb: -------------------------------------------------------------------------------- 1 | module SpecHelpers 2 | module Payload 3 | def payload_for(type, language = nil, extra = {}) 4 | payload = Marshal.load( 5 | Marshal.dump( 6 | PAYLOADS.fetch(type).deep_symbolize_keys 7 | ) 8 | ) 9 | 10 | if language 11 | language = language.to_s 12 | payload.deep_merge!(config: { language: language }) 13 | 14 | payload.deep_merge!( 15 | Marshal.load( 16 | Marshal.dump( 17 | PAYLOAD_LANGUAGE_OVERRIDES.fetch( 18 | language.to_sym, {} 19 | ).deep_symbolize_keys 20 | ) 21 | ) 22 | ) 23 | end 24 | 25 | payload.deep_merge(extra) 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/spec_helpers/shell.rb: -------------------------------------------------------------------------------- 1 | require 'shellwords' 2 | 3 | module SpecHelpers 4 | module Shell 5 | def shell_include?(code, string) 6 | code.include?(string.shellescape) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/cache_slug_extras.rb: -------------------------------------------------------------------------------- 1 | # concatenation of: 2 | # 1. config[:os] 3 | # 2. config[:dist], (nil for specs) 4 | # 3. SHA256 digest of env var array ["FOO=foo"], joined with '=' 5 | # i.e., OpenSSL::Digest::SHA256.hexdigest(Array(["FOO=foo"]).sort.join('=')) 6 | # with '-' 7 | CACHE_SLUG_EXTRAS='linux-d5b6dcf6629e552946e7baf3fc0aca4de552e1cd76b596a2800194fe085a53f7' 8 | CACHE_SLUG_EXTRAS_FREEBSD='freebsd-d5b6dcf6629e552946e7baf3fc0aca4de552e1cd76b596a2800194fe085a53f7' 9 | -------------------------------------------------------------------------------- /spec/support/github_apps.rb: -------------------------------------------------------------------------------- 1 | ENV['GITHUB_PRIVATE_PEM'] = <<~pem 2 | -----BEGIN RSA PRIVATE KEY----- 3 | MIICXAIBAAKBgQCDmxahOu0HsiWI57rXMGaR8Zaoq2YlyfXsDGZfgRzZn2EFxc4V 4 | GC1j7ecT+H/jqysdG4ZqeAJPkpBOf1f1sf4S2cxfYoVO49+LnVTapfkcA13HB0tO 5 | rWfLZrUMTFjCSJeKqwHvM4w8KFYekPHThV5H3z6i/Gczs1J1D6j6k/AIywIDAQAB 6 | AoGAYdC1YyRu5BduenDxl9srgTG0rqymAVQ4ajdVJ4rJLJ6e+DFq2JbdtbYu19MN 7 | CuQ/6SR6JUwJO6dNhmpzr/OZSMjOfLL4k6AjciecrRdxg5R4ze+Ng/EzF7IDyTEj 8 | djwRWWNClxzmaTBFc7xQE4eOjFB+RvEuhB7FG+vLZriLjfECQQDZIV1mXofT4WEC 9 | Jwd47lopZku3d6l9qTIHZhdsbXb2ESJR3XpdWfeM/PtxkZW6/DXGSb+v2STYcXLU 10 | I0vEJ5QdAkEAmypPtSGU+Q/zJ3JKhPRU3Gnvla/eKfU7R+RopoutX4pB7+eNd5O/ 11 | kCkyFMrLS0q53HDJRrP5veSkV4Gs5h4sBwJANpOdX3LZX1eiQ6E9zpbS0N8mnwoT 12 | 70MNETEHKDjnkvhBkSRDcp1/jM+2ABjg8uwcNCgrZ28EROdXPp1UmQx9vQJAH3th 13 | Or36jOIYkqtUxU8RnLr9umA5ckfoZDjKpuf2IElcAYH4qQdYObayC5ft0XPy6/AS 14 | Vn8Tr9yhH4QXAYWjpwJBAKdu0Zi/905s0sEWoxRP4v0ChSu122cuwQ1cymD9Kx4W 15 | ZxwkYh9bnSuvD26L6BPFcjprp2WDEr+h+OJJBFcZWFU= 16 | -----END RSA PRIVATE KEY----- 17 | pem 18 | -------------------------------------------------------------------------------- /spec/support/logger.rb: -------------------------------------------------------------------------------- 1 | module SpecHelpers 2 | module Logger 3 | def self.included(const) 4 | const.module_eval do 5 | let(:stdout) { io.string } 6 | let(:io) { StringIO.new } 7 | let(:logger) { Travis::Build.logger } 8 | before { Travis::Build.logger = Travis::Logger.new(io) } 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/matchers/script.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :include_shell do |expected| 2 | match do |code| 3 | shell_include?(code, expected) 4 | end 5 | 6 | failure_message do |code| 7 | "Expected the following script to include #{expected.inspect}, but it didn't:\n\n#{code}" 8 | end 9 | 10 | failure_message_when_negated do |code| 11 | "Expected the generated script to not include #{expected.inspect}." 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /spec/support/matchers/sexp.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :match_sexp do |expected| 2 | match do |sexp| 3 | sexp_find(sexp, expected).any? 4 | end 5 | 6 | failure_message do |sexp| 7 | "Expected the following sexp to include #{expected}, but it didn't:\n\n#{sexp}" 8 | end 9 | 10 | failure_message_when_negated do |sexp| 11 | "Expected the following sexp to not include #{expected}, but it did:\n\n#{sexp}" 12 | end 13 | end 14 | 15 | RSpec::Matchers.define :include_sexp do |expected| 16 | match do |sexp| 17 | sexp_includes?(sexp, expected) 18 | end 19 | 20 | failure_message do |sexp| 21 | "Expected the generated sexp to include:\n\n#{expected}#{similar_nodes(sexp, expected.first)}" 22 | end 23 | 24 | def similar_nodes(sexp, type) 25 | sexps = sexp_filter(sexp, [expected.first]) 26 | sexps = sexps.map(&:inspect).join("\n") 27 | "\n\nFound the following similar nodes:\n\n#{sexps}" unless sexp.empty? 28 | end 29 | 30 | failure_message_when_negated do |sexp| 31 | "Expected the following sexp to not include #{expected}" 32 | end 33 | end 34 | 35 | RSpec::Matchers.define :include_deprecation_sexp do |msg| 36 | match do |sexp| 37 | sexp = sexp_filter(sexp, [:echo]).detect { |echo| echo[1] =~ msg } 38 | sexp && sexp[1][0, 10] == 'DEPRECATED' && sexp[2] && sexp[2][:ansi] = :red 39 | end 40 | 41 | failure_message do |sexp| 42 | "Expected the following sexp to include #{expected}, but it didn't:\n\n#{sexp}" 43 | end 44 | 45 | failure_message_when_negated do |sexp| 46 | "Expected the following sexp to not include #{expected}, but it did:\n\n#{sexp}" 47 | end 48 | end 49 | --------------------------------------------------------------------------------