shipit-engine 0.30.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -4
- data/Rakefile +4 -2
- data/app/assets/images/magic-solid.svg +1 -0
- data/app/assets/javascripts/shipit/repositories_search.js.coffee +60 -0
- data/app/assets/javascripts/shipit/{search.js.coffee → stack_search.js.coffee} +0 -0
- data/app/assets/stylesheets/_pages/_deploy.scss +0 -2
- data/app/assets/stylesheets/_pages/_repositories.scss +148 -0
- data/app/assets/stylesheets/_pages/_stacks.scss +19 -3
- data/app/assets/stylesheets/merge_status.scss +0 -3
- data/app/assets/stylesheets/shipit.scss +1 -0
- data/app/controllers/concerns/shipit/active_model_serializers_patch.rb +1 -0
- data/app/controllers/concerns/shipit/api/cacheable.rb +1 -0
- data/app/controllers/concerns/shipit/api/paginable.rb +3 -2
- data/app/controllers/concerns/shipit/api/rendering.rb +5 -4
- data/app/controllers/concerns/shipit/authentication.rb +3 -2
- data/app/controllers/concerns/shipit/pagination.rb +2 -1
- data/app/controllers/shipit/api/base_controller.rb +11 -6
- data/app/controllers/shipit/api/ccmenu_controller.rb +2 -1
- data/app/controllers/shipit/api/commits_controller.rb +2 -1
- data/app/controllers/shipit/api/deploys_controller.rb +6 -3
- data/app/controllers/shipit/api/hooks_controller.rb +6 -5
- data/app/controllers/shipit/api/locks_controller.rb +5 -4
- data/app/controllers/shipit/api/merge_requests_controller.rb +37 -0
- data/app/controllers/shipit/api/outputs_controller.rb +2 -1
- data/app/controllers/shipit/api/release_statuses_controller.rb +3 -2
- data/app/controllers/shipit/api/rollbacks_controller.rb +34 -0
- data/app/controllers/shipit/api/stacks_controller.rb +32 -5
- data/app/controllers/shipit/api/tasks_controller.rb +6 -5
- data/app/controllers/shipit/api_clients_controller.rb +4 -3
- data/app/controllers/shipit/ccmenu_url_controller.rb +4 -3
- data/app/controllers/shipit/commit_checks_controller.rb +2 -1
- data/app/controllers/shipit/commits_controller.rb +2 -1
- data/app/controllers/shipit/deploys_controller.rb +4 -3
- data/app/controllers/shipit/github_authentication_controller.rb +4 -3
- data/app/controllers/shipit/merge_requests_controller.rb +31 -0
- data/app/controllers/shipit/merge_status_controller.rb +31 -30
- data/app/controllers/shipit/release_statuses_controller.rb +3 -2
- data/app/controllers/shipit/repositories_controller.rb +74 -0
- data/app/controllers/shipit/rollbacks_controller.rb +3 -2
- data/app/controllers/shipit/shipit_controller.rb +2 -1
- data/app/controllers/shipit/stacks_controller.rb +24 -9
- data/app/controllers/shipit/status_controller.rb +2 -1
- data/app/controllers/shipit/tasks_controller.rb +7 -6
- data/app/controllers/shipit/webhooks_controller.rb +26 -6
- data/app/helpers/shipit/chunks_helper.rb +3 -2
- data/app/helpers/shipit/deploys_helper.rb +4 -3
- data/app/helpers/shipit/github_url_helper.rb +9 -0
- data/app/helpers/shipit/merge_status_helper.rb +1 -0
- data/app/helpers/shipit/shipit_helper.rb +1 -1
- data/app/helpers/shipit/stacks_helper.rb +5 -0
- data/app/helpers/shipit/tasks_helper.rb +1 -0
- data/app/jobs/shipit/background_job.rb +4 -0
- data/app/jobs/shipit/background_job/unique.rb +1 -0
- data/app/jobs/shipit/cache_deploy_spec_job.rb +1 -0
- data/app/jobs/shipit/chunk_rollup_job.rb +4 -0
- data/app/jobs/shipit/clear_git_cache_job.rb +1 -0
- data/app/jobs/shipit/continuous_delivery_job.rb +2 -1
- data/app/jobs/shipit/create_on_github_job.rb +7 -1
- data/app/jobs/shipit/create_release_statuses_job.rb +1 -0
- data/app/jobs/shipit/deferred_touch_job.rb +4 -0
- data/app/jobs/shipit/deliver_hook_job.rb +2 -1
- data/app/jobs/shipit/destroy_job.rb +1 -0
- data/app/jobs/shipit/destroy_repository_job.rb +24 -0
- data/app/jobs/shipit/destroy_stack_job.rb +3 -2
- data/app/jobs/shipit/emit_event_job.rb +2 -1
- data/app/jobs/shipit/fetch_commit_stats_job.rb +1 -0
- data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -0
- data/app/jobs/shipit/github_sync_job.rb +15 -10
- data/app/jobs/shipit/mark_deploy_healthy_job.rb +1 -0
- data/app/jobs/shipit/perform_commit_checks_job.rb +1 -0
- data/app/jobs/shipit/perform_task_job.rb +5 -92
- data/app/jobs/shipit/process_merge_requests_job.rb +32 -0
- data/app/jobs/shipit/purge_old_deliveries_job.rb +1 -0
- data/app/jobs/shipit/reap_dead_tasks_job.rb +21 -0
- data/app/jobs/shipit/refresh_check_runs_job.rb +1 -0
- data/app/jobs/shipit/refresh_github_user_job.rb +1 -0
- data/app/jobs/shipit/refresh_merge_request_job.rb +11 -0
- data/app/jobs/shipit/refresh_statuses_job.rb +1 -0
- data/app/jobs/shipit/setup_github_hook_job.rb +1 -0
- data/app/jobs/shipit/update_estimated_deploy_duration_job.rb +1 -0
- data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +5 -4
- data/app/models/concerns/shipit/deferred_touch.rb +4 -3
- data/app/models/shipit/anonymous_user.rb +15 -2
- data/app/models/shipit/api_client.rb +3 -2
- data/app/models/shipit/application_record.rb +2 -1
- data/app/models/shipit/check_run.rb +41 -4
- data/app/models/shipit/command_line_user.rb +5 -0
- data/app/models/shipit/commit.rb +42 -24
- data/app/models/shipit/commit_checks.rb +15 -13
- data/app/models/shipit/commit_deployment.rb +6 -5
- data/app/models/shipit/commit_deployment_status.rb +5 -4
- data/app/models/shipit/commit_message.rb +1 -0
- data/app/models/shipit/delivery.rb +4 -3
- data/app/models/shipit/deploy.rb +23 -28
- data/app/models/shipit/deploy_spec.rb +38 -7
- data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -0
- data/app/models/shipit/deploy_spec/capistrano_discovery.rb +1 -0
- data/app/models/shipit/deploy_spec/file_system.rb +20 -7
- data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +1 -0
- data/app/models/shipit/deploy_spec/lerna_discovery.rb +13 -4
- data/app/models/shipit/deploy_spec/npm_discovery.rb +5 -4
- data/app/models/shipit/deploy_spec/pypi_discovery.rb +1 -0
- data/app/models/shipit/deploy_spec/rubygems_discovery.rb +1 -0
- data/app/models/shipit/deploy_stats.rb +2 -1
- data/app/models/shipit/duration.rb +5 -2
- data/app/models/shipit/ephemeral_commit_checks.rb +1 -0
- data/app/models/shipit/github_hook.rb +2 -1
- data/app/models/shipit/github_status.rb +2 -1
- data/app/models/shipit/hook.rb +34 -7
- data/app/models/shipit/membership.rb +3 -2
- data/app/models/shipit/merge_request.rb +304 -0
- data/app/models/shipit/output_chunk.rb +7 -2
- data/app/models/shipit/provisioning_handler.rb +32 -0
- data/app/models/shipit/provisioning_handler/base.rb +30 -0
- data/app/models/shipit/provisioning_handler/unregistered_provisioning_handler.rb +35 -0
- data/app/models/shipit/pull_request.rb +28 -266
- data/app/models/shipit/pull_request_assignment.rb +10 -0
- data/app/models/shipit/record.rb +18 -0
- data/app/models/shipit/release_status.rb +4 -3
- data/app/models/shipit/repository.rb +71 -6
- data/app/models/shipit/review_stack.rb +130 -0
- data/app/models/shipit/review_stack_provisioning_queue.rb +39 -0
- data/app/models/shipit/rollback.rb +1 -0
- data/app/models/shipit/stack.rb +144 -44
- data/app/models/shipit/status.rb +3 -2
- data/app/models/shipit/status/common.rb +7 -6
- data/app/models/shipit/status/group.rb +2 -1
- data/app/models/shipit/status/missing.rb +2 -1
- data/app/models/shipit/status/unknown.rb +2 -1
- data/app/models/shipit/task.rb +98 -12
- data/app/models/shipit/task_definition.rb +1 -0
- data/app/models/shipit/task_execution_strategy/base.rb +20 -0
- data/app/models/shipit/task_execution_strategy/default.rb +109 -0
- data/app/models/shipit/team.rb +6 -3
- data/app/models/shipit/undeployed_commit.rb +1 -0
- data/app/models/shipit/unlimited_api_client.rb +1 -0
- data/app/models/shipit/user.rb +19 -8
- data/app/models/shipit/variable_definition.rb +1 -0
- data/app/models/shipit/webhooks.rb +11 -0
- data/app/models/shipit/webhooks/handlers/check_suite_handler.rb +1 -0
- data/app/models/shipit/webhooks/handlers/handler.rb +1 -0
- data/app/models/shipit/webhooks/handlers/membership_handler.rb +1 -0
- data/app/models/shipit/webhooks/handlers/pull_request/assigned_handler.rb +74 -0
- data/app/models/shipit/webhooks/handlers/pull_request/closed_handler.rb +68 -0
- data/app/models/shipit/webhooks/handlers/pull_request/edited_handler.rb +74 -0
- data/app/models/shipit/webhooks/handlers/pull_request/label_capturing_handler.rb +127 -0
- data/app/models/shipit/webhooks/handlers/pull_request/labeled_handler.rb +106 -0
- data/app/models/shipit/webhooks/handlers/pull_request/opened_handler.rb +83 -0
- data/app/models/shipit/webhooks/handlers/pull_request/reopened_handler.rb +88 -0
- data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +103 -0
- data/app/models/shipit/webhooks/handlers/pull_request/unlabeled_handler.rb +107 -0
- data/app/models/shipit/webhooks/handlers/push_handler.rb +5 -1
- data/app/models/shipit/webhooks/handlers/status_handler.rb +1 -0
- data/app/serializers/concerns/shipit/conditional_attributes.rb +1 -0
- data/app/serializers/shipit/anonymous_user_serializer.rb +1 -0
- data/app/serializers/shipit/command_line_user_serializer.rb +1 -0
- data/app/serializers/shipit/commit_serializer.rb +1 -0
- data/app/serializers/shipit/deploy_serializer.rb +8 -1
- data/app/serializers/shipit/hook_serializer.rb +1 -0
- data/app/serializers/shipit/merge_request_serializer.rb +21 -0
- data/app/serializers/shipit/pull_request_serializer.rb +6 -8
- data/app/serializers/shipit/review_stack_serializer.rb +7 -0
- data/app/serializers/shipit/rollback_serializer.rb +1 -0
- data/app/serializers/shipit/short_commit_serializer.rb +1 -0
- data/app/serializers/shipit/stack_serializer.rb +8 -6
- data/app/serializers/shipit/tail_task_serializer.rb +11 -2
- data/app/serializers/shipit/task_serializer.rb +2 -17
- data/app/serializers/shipit/user_serializer.rb +6 -1
- data/app/validators/ascii_only_validator.rb +1 -0
- data/app/validators/subset_validator.rb +2 -1
- data/app/views/layouts/merge_status.html.erb +1 -1
- data/app/views/layouts/shipit.html.erb +1 -1
- data/app/views/shipit/_variables.html.erb +1 -1
- data/app/views/shipit/ccmenu/project.xml.builder +2 -1
- data/app/views/shipit/deploys/show.html.erb +2 -2
- data/app/views/shipit/merge_requests/_merge_request.html.erb +29 -0
- data/app/views/shipit/{pull_requests → merge_requests}/index.html.erb +2 -2
- data/app/views/shipit/merge_requests/merge_requests/_pull_request.html.erb +29 -0
- data/app/views/shipit/merge_requests/merge_requests/index.html.erb +20 -0
- data/app/views/shipit/merge_status/_merge_queue_button.html.erb +3 -3
- data/app/views/shipit/merge_status/backlogged.html.erb +1 -1
- data/app/views/shipit/merge_status/failure.html.erb +1 -1
- data/app/views/shipit/merge_status/locked.html.erb +1 -1
- data/app/views/shipit/merge_status/success.html.erb +2 -2
- data/app/views/shipit/repositories/_header.html.erb +19 -0
- data/app/views/shipit/repositories/index.html.erb +31 -0
- data/app/views/shipit/repositories/new.html.erb +23 -0
- data/app/views/shipit/repositories/settings.html.erb +53 -0
- data/app/views/shipit/repositories/show.html.erb +30 -0
- data/app/views/shipit/stacks/_banners.html.erb +15 -1
- data/app/views/shipit/stacks/_header.html.erb +20 -7
- data/app/views/shipit/stacks/_stack.html.erb +8 -0
- data/app/views/shipit/stacks/all_tasks.html.erb +28 -0
- data/app/views/shipit/stacks/index.html.erb +3 -2
- data/app/views/shipit/stacks/new.html.erb +1 -1
- data/app/views/shipit/stacks/settings.html.erb +5 -5
- data/app/views/shipit/stacks/show.html.erb +1 -1
- data/app/views/shipit/tasks/_task_output.html.erb +1 -1
- data/app/views/shipit/tasks/show.html.erb +1 -1
- data/config/initializers/inflections.rb +2 -1
- data/config/locales/en.yml +4 -3
- data/config/routes.rb +25 -7
- data/config/secrets.development.example.yml +24 -0
- data/config/secrets.development.shopify.yml +20 -9
- data/db/migrate/20200226211925_add_index_to_tasks_status.rb +5 -0
- data/db/migrate/20200427135152_add_pull_request_head_sha_to_commit.rb +5 -0
- data/db/migrate/20200615181558_add_rollback_once_aborted_to.rb +5 -0
- data/db/migrate/20200706145406_add_review_stacks.rb +12 -0
- data/db/migrate/20200804144639_rename_pull_request_to_merge_request.rb +7 -0
- data/db/migrate/20200804161512_rename_commits_pull_request_id_to_merge_request_id.rb +5 -0
- data/db/migrate/20200813134712_recreate_shipit_pull_requests.rb +22 -0
- data/db/migrate/20200813194056_create_pull_request_assignments.rb +8 -0
- data/db/migrate/20201001125502_add_provision_pr_stacks_flag_to_repositories.rb +7 -0
- data/db/migrate/20201008145809_add_retry_attempt_to_tasks.rb +5 -0
- data/db/migrate/20201008152744_add_max_retries_to_tasks.rb +5 -0
- data/db/migrate/20210325194053_remove_stacks_branch_default.rb +5 -0
- data/db/migrate/20210504200438_add_github_updated_at_to_check_runs.rb +5 -0
- data/lib/shipit.rb +61 -17
- data/lib/shipit/cast_value.rb +1 -0
- data/lib/shipit/command.rb +20 -21
- data/lib/shipit/commands.rb +14 -6
- data/lib/shipit/csv_serializer.rb +1 -0
- data/lib/shipit/deploy_commands.rb +1 -0
- data/lib/shipit/engine.rb +9 -2
- data/lib/shipit/environment_variables.rb +11 -1
- data/lib/shipit/first_parent_commits_iterator.rb +1 -0
- data/lib/shipit/flock.rb +9 -1
- data/lib/shipit/github_app.rb +15 -12
- data/lib/shipit/github_http_cache_middleware.rb +1 -0
- data/lib/shipit/null_serializer.rb +1 -0
- data/lib/shipit/octokit_check_runs.rb +3 -2
- data/lib/shipit/octokit_iterator.rb +4 -3
- data/lib/shipit/paginator.rb +3 -2
- data/lib/shipit/review_stack_commands.rb +8 -0
- data/lib/shipit/rollback_commands.rb +1 -0
- data/lib/shipit/same_site_cookie_middleware.rb +29 -0
- data/lib/shipit/simple_message_verifier.rb +3 -2
- data/lib/shipit/stack_commands.rb +37 -7
- data/lib/shipit/stat.rb +1 -0
- data/lib/shipit/task_commands.rb +23 -16
- data/lib/shipit/version.rb +2 -1
- data/lib/snippets/publish-lerna-independent-packages +35 -34
- data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
- data/lib/snippets/release-gem +5 -1
- data/lib/tasks/cron.rake +13 -2
- data/lib/tasks/dev.rake +3 -2
- data/lib/tasks/shipit.rake +15 -14
- data/lib/tasks/teams.rake +1 -0
- data/test/controllers/api/base_controller_test.rb +3 -2
- data/test/controllers/api/ccmenu_controller_test.rb +9 -8
- data/test/controllers/api/commits_controller_test.rb +3 -2
- data/test/controllers/api/deploys_controller_test.rb +32 -14
- data/test/controllers/api/hooks_controller_test.rb +8 -7
- data/test/controllers/api/locks_controller_test.rb +7 -6
- data/test/controllers/api/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +17 -16
- data/test/controllers/api/outputs_controller_test.rb +3 -1
- data/test/controllers/api/release_statuses_controller_test.rb +2 -1
- data/test/controllers/api/rollback_controller_test.rb +113 -0
- data/test/controllers/api/stacks_controller_test.rb +71 -16
- data/test/controllers/api/tasks_controller_test.rb +13 -12
- data/test/controllers/api_clients_controller_test.rb +5 -4
- data/test/controllers/ccmenu_controller_test.rb +4 -3
- data/test/controllers/commit_checks_controller_test.rb +4 -3
- data/test/controllers/commits_controller_test.rb +3 -2
- data/test/controllers/deploys_controller_test.rb +32 -21
- data/test/controllers/github_authentication_controller_test.rb +1 -0
- data/test/controllers/merge_requests_controller_test.rb +32 -0
- data/test/controllers/merge_status_controller_test.rb +7 -6
- data/test/controllers/release_statuses_controller_test.rb +3 -2
- data/test/controllers/repositories_controller_test.rb +71 -0
- data/test/controllers/rollbacks_controller_test.rb +9 -8
- data/test/controllers/stacks_controller_test.rb +41 -19
- data/test/controllers/status_controller_test.rb +1 -0
- data/test/controllers/tasks_controller_test.rb +32 -19
- data/test/controllers/webhooks_controller_test.rb +33 -17
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/config/application.rb +7 -2
- data/test/dummy/config/database.yml +9 -0
- data/test/dummy/config/environments/development.rb +3 -4
- data/test/dummy/config/environments/test.rb +2 -5
- data/test/dummy/config/secrets_double_github_app.yml +79 -0
- data/test/dummy/db/schema.rb +59 -17
- data/test/dummy/db/seeds.rb +2 -1
- data/test/fixtures/payloads/check_suite_master.json +4 -32
- data/test/fixtures/payloads/invalid_pull_request.json +117 -0
- data/test/fixtures/payloads/provision_disabled_pull_request.json +454 -0
- data/test/fixtures/payloads/pull_request_assigned.json +480 -0
- data/test/fixtures/payloads/pull_request_closed.json +454 -0
- data/test/fixtures/payloads/pull_request_labeled.json +461 -0
- data/test/fixtures/payloads/pull_request_opened.json +454 -0
- data/test/fixtures/payloads/pull_request_reopened.json +454 -0
- data/test/fixtures/payloads/pull_request_unlabeled.json +454 -0
- data/test/fixtures/payloads/pull_request_with_no_repo.json +454 -0
- data/test/fixtures/payloads/push_master.json +1 -1
- data/test/fixtures/payloads/push_not_master.json +1 -1
- data/test/fixtures/shipit/commits.yml +31 -3
- data/test/fixtures/shipit/hooks.yml +1 -0
- data/test/fixtures/shipit/merge_requests.yml +141 -0
- data/test/fixtures/shipit/pull_request_assignments.yml +3 -0
- data/test/fixtures/shipit/pull_requests.yml +10 -131
- data/test/fixtures/shipit/repositories.yml +5 -0
- data/test/fixtures/shipit/stacks.yml +235 -14
- data/test/fixtures/shipit/statuses.yml +9 -0
- data/test/fixtures/shipit/tasks.yml +4 -1
- data/test/fixtures/shipit/users.yml +7 -0
- data/test/fixtures/timeout +2 -1
- data/test/helpers/api_helper.rb +1 -0
- data/test/helpers/fixture_aliases_helper.rb +1 -0
- data/test/helpers/hooks_helper.rb +2 -1
- data/test/helpers/json_helper.rb +20 -12
- data/test/helpers/links_helper.rb +4 -3
- data/test/helpers/payloads_helper.rb +5 -0
- data/test/helpers/queries_helper.rb +3 -2
- data/test/jobs/cache_deploy_spec_job_test.rb +2 -1
- data/test/jobs/chunk_rollup_job_test.rb +16 -1
- data/test/jobs/deliver_hook_job_test.rb +1 -0
- data/test/jobs/destroy_repository_job_test.rb +27 -0
- data/test/jobs/destroy_stack_job_test.rb +1 -0
- data/test/jobs/emit_event_job_test.rb +2 -1
- data/test/jobs/fetch_commit_stats_job_test.rb +1 -0
- data/test/jobs/fetch_deployed_revision_job_test.rb +1 -0
- data/test/jobs/github_sync_job_test.rb +3 -1
- data/test/jobs/mark_deploy_healthy_job_test.rb +1 -0
- data/test/jobs/perform_task_job_test.rb +12 -11
- data/test/jobs/{merge_pull_requests_job_test.rb → process_merge_requests_job_test.rb} +19 -18
- data/test/jobs/purge_old_deliveries_job_test.rb +1 -0
- data/test/jobs/reap_dead_tasks_job_test.rb +68 -0
- data/test/jobs/refresh_github_user_job_test.rb +1 -0
- data/test/jobs/refresh_status_job_test.rb +1 -0
- data/test/jobs/unique_job_test.rb +1 -0
- data/test/jobs/update_github_last_deployed_ref_job_test.rb +1 -0
- data/test/lib/shipit/deploy_commands_test.rb +16 -0
- data/test/lib/shipit/task_commands_test.rb +17 -0
- data/test/middleware/same_site_cookie_middleware_test.rb +52 -0
- data/test/models/api_client_test.rb +1 -0
- data/test/models/commit_checks_test.rb +1 -0
- data/test/models/commit_deployment_status_test.rb +4 -3
- data/test/models/commit_deployment_test.rb +2 -1
- data/test/models/commits_test.rb +96 -19
- data/test/models/delivery_test.rb +2 -1
- data/test/models/deploy_spec_test.rb +110 -65
- data/test/models/deploy_stats_test.rb +1 -0
- data/test/models/deploys_test.rb +197 -36
- data/test/models/duration_test.rb +1 -0
- data/test/models/github_hook_test.rb +1 -0
- data/test/models/hook_test.rb +47 -10
- data/test/models/membership_test.rb +1 -0
- data/test/models/{pull_request_test.rb → merge_request_test.rb} +53 -37
- data/test/models/pull_request_assignment_test.rb +16 -0
- data/test/models/release_statuses_test.rb +1 -0
- data/test/models/rollbacks_test.rb +1 -0
- data/test/models/shipit/check_run_test.rb +125 -5
- data/test/models/shipit/provisioning_handler/base_test.rb +33 -0
- data/test/models/shipit/provisioning_handler/unregistered_provisioning_handler_test.rb +49 -0
- data/test/models/shipit/provisioning_handler_test.rb +64 -0
- data/test/models/shipit/pull_request_test.rb +52 -0
- data/test/models/shipit/repository_test.rb +6 -1
- data/test/models/shipit/review_stack_provision_status_test.rb +77 -0
- data/test/models/shipit/review_stack_provisioning_queue_test.rb +63 -0
- data/test/models/shipit/review_stack_test.rb +91 -0
- data/test/models/{stacks_test.rb → shipit/stacks_test.rb} +121 -16
- data/test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb +45 -0
- data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +192 -0
- data/test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb +47 -0
- data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +209 -0
- data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +332 -0
- data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +238 -0
- data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +282 -0
- data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +107 -0
- data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +324 -0
- data/test/models/shipit/{wehbooks → webhooks}/handlers_test.rb +1 -0
- data/test/models/status/group_test.rb +1 -0
- data/test/models/status/missing_test.rb +1 -0
- data/test/models/status_test.rb +1 -0
- data/test/models/task_definitions_test.rb +9 -8
- data/test/models/tasks_test.rb +81 -1
- data/test/models/team_test.rb +4 -2
- data/test/models/undeployed_commits_test.rb +1 -0
- data/test/models/users_test.rb +13 -5
- data/test/serializers/shipit/pull_request_serializer_test.rb +29 -0
- data/test/test_command_integration.rb +3 -2
- data/test/test_helper.rb +49 -31
- data/test/unit/anonymous_user_serializer_test.rb +14 -0
- data/test/unit/command_test.rb +16 -10
- data/test/unit/commands_test.rb +1 -0
- data/test/unit/commit_serializer_test.rb +16 -0
- data/test/unit/csv_serializer_test.rb +3 -2
- data/test/unit/deploy_commands_test.rb +75 -18
- data/test/unit/deploy_serializer_test.rb +17 -0
- data/test/unit/environment_variables_test.rb +5 -4
- data/test/unit/github_app_test.rb +3 -3
- data/test/unit/github_apps_test.rb +416 -0
- data/test/unit/github_url_helper_test.rb +6 -0
- data/test/unit/rollback_commands_test.rb +2 -1
- data/test/unit/shipit_deployment_checks_test.rb +77 -0
- data/test/unit/shipit_helper_test.rb +17 -0
- data/test/unit/shipit_task_execution_strategy_test.rb +47 -0
- data/test/unit/shipit_test.rb +15 -0
- data/test/unit/user_serializer_test.rb +14 -0
- data/test/unit/variable_definition_test.rb +1 -0
- metadata +320 -178
- data/app/controllers/shipit/api/pull_requests_controller.rb +0 -36
- data/app/controllers/shipit/pull_requests_controller.rb +0 -30
- data/app/jobs/shipit/merge_pull_requests_job.rb +0 -31
- data/app/jobs/shipit/refresh_pull_request_job.rb +0 -10
- data/app/views/shipit/pull_requests/_pull_request.html.erb +0 -29
- data/test/controllers/pull_requests_controller_test.rb +0 -31
- data/test/fixtures/shipit/output_chunks.yml +0 -47
- data/test/models/output_chunk_test.rb +0 -20
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Shipit
|
|
3
|
+
class Record < ActiveRecord::Base
|
|
4
|
+
self.abstract_class = true
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
def serializer_class
|
|
8
|
+
if defined? @serializer_class
|
|
9
|
+
@serializer_class
|
|
10
|
+
else
|
|
11
|
+
@serializer_class = "#{name}Serializer".safe_constantize
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
delegate :serializer_class, to: :class
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Shipit
|
|
2
|
-
class ReleaseStatus <
|
|
3
|
+
class ReleaseStatus < Record
|
|
3
4
|
MAX_DESCRIPTION_LENGTH = 140
|
|
4
5
|
include DeferredTouch
|
|
5
6
|
|
|
@@ -13,7 +14,7 @@ module Shipit
|
|
|
13
14
|
scope :to_be_created, -> { where(github_id: nil).order(id: :asc) }
|
|
14
15
|
|
|
15
16
|
STATES = %w(pending success failure error).freeze
|
|
16
|
-
validates :state, presence: true, inclusion: {in: STATES}
|
|
17
|
+
validates :state, presence: true, inclusion: { in: STATES }
|
|
17
18
|
|
|
18
19
|
def create_status_on_github!
|
|
19
20
|
return true if github_id?
|
|
@@ -24,7 +25,7 @@ module Shipit
|
|
|
24
25
|
private
|
|
25
26
|
|
|
26
27
|
def create_status_on_github
|
|
27
|
-
|
|
28
|
+
stack.github_api.create_status(
|
|
28
29
|
stack.github_repo_name,
|
|
29
30
|
commit.sha,
|
|
30
31
|
state,
|
|
@@ -1,4 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Shipit
|
|
3
|
+
class NullRepository
|
|
4
|
+
def id
|
|
5
|
+
nil
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def stacks
|
|
9
|
+
Shipit::Stack.none
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def review_stacks
|
|
13
|
+
Shipit::ReviewStack.none
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def review_stacks_enabled
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def provisioning_behavior_allow_all?
|
|
21
|
+
false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def provisioning_behavior_allow_with_label?
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def provisioning_behavior_prevent_with_label?
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
2
33
|
class Repository < ApplicationRecord
|
|
3
34
|
OWNER_MAX_SIZE = 39
|
|
4
35
|
private_constant :OWNER_MAX_SIZE
|
|
@@ -6,13 +37,17 @@ module Shipit
|
|
|
6
37
|
NAME_MAX_SIZE = 100
|
|
7
38
|
private_constant :NAME_MAX_SIZE
|
|
8
39
|
|
|
9
|
-
validates :name, uniqueness: {scope: %i(owner), case_sensitive: false,
|
|
10
|
-
|
|
40
|
+
validates :name, uniqueness: { scope: %i(owner), case_sensitive: false,
|
|
41
|
+
message: 'cannot be used more than once', }
|
|
11
42
|
validates :owner, :name, presence: true, ascii_only: true
|
|
12
|
-
validates :owner, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: OWNER_MAX_SIZE}
|
|
13
|
-
validates :name, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: NAME_MAX_SIZE}
|
|
43
|
+
validates :owner, format: { with: /\A[a-z0-9_\-\.]+\z/ }, length: { maximum: OWNER_MAX_SIZE }
|
|
44
|
+
validates :name, format: { with: /\A[a-z0-9_\-\.]+\z/ }, length: { maximum: NAME_MAX_SIZE }
|
|
14
45
|
|
|
15
46
|
has_many :stacks, dependent: :destroy
|
|
47
|
+
has_many :review_stacks, dependent: :destroy
|
|
48
|
+
|
|
49
|
+
PROVISIONING_BEHAVIORS = %w(allow_all allow_with_label prevent_with_label).freeze
|
|
50
|
+
enum provisioning_behavior: PROVISIONING_BEHAVIORS.zip(PROVISIONING_BEHAVIORS).to_h, _prefix: :provisioning_behavior
|
|
16
51
|
|
|
17
52
|
def self.from_github_repo_name(github_repo_name)
|
|
18
53
|
repo_owner, repo_name = github_repo_name.downcase.split('/')
|
|
@@ -27,12 +62,42 @@ module Shipit
|
|
|
27
62
|
super(o&.downcase)
|
|
28
63
|
end
|
|
29
64
|
|
|
65
|
+
def github_repo_name
|
|
66
|
+
[owner, name].join('/')
|
|
67
|
+
end
|
|
68
|
+
|
|
30
69
|
def http_url
|
|
31
|
-
|
|
70
|
+
github_app.url(full_name)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def full_name
|
|
74
|
+
"#{owner}/#{name}"
|
|
32
75
|
end
|
|
33
76
|
|
|
34
77
|
def git_url
|
|
35
|
-
"https://#{
|
|
78
|
+
"https://#{github_app.domain}/#{owner}/#{name}.git"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def schedule_for_destroy!
|
|
82
|
+
DestroyRepositoryJob.perform_later(self)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def to_param
|
|
86
|
+
github_repo_name
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.from_param!(param)
|
|
90
|
+
repo_owner, repo_name = param.split('/')
|
|
91
|
+
where(
|
|
92
|
+
owner: repo_owner.downcase,
|
|
93
|
+
name: repo_name.downcase,
|
|
94
|
+
).first!
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
protected
|
|
98
|
+
|
|
99
|
+
def github_app
|
|
100
|
+
Shipit.github(organization: owner)
|
|
36
101
|
end
|
|
37
102
|
end
|
|
38
103
|
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shipit
|
|
4
|
+
class ReviewStack < Shipit::Stack
|
|
5
|
+
def self.clear_stale_caches
|
|
6
|
+
Shipit::ReviewStack.where(
|
|
7
|
+
"archived_since > :earliest AND archived_since < :latest",
|
|
8
|
+
earliest: 1.day.ago,
|
|
9
|
+
latest: 1.hour.ago
|
|
10
|
+
).find_each do |review_stack|
|
|
11
|
+
review_stack.clear_local_files
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.delete_old_deployment_directories
|
|
16
|
+
Shipit::Deploy.not_active.where(
|
|
17
|
+
"created_at > :earliest AND updated_at < :latest",
|
|
18
|
+
earliest: 1.day.ago,
|
|
19
|
+
latest: 1.hour.ago
|
|
20
|
+
).find_each do |deploy|
|
|
21
|
+
Shipit::Commands.for(deploy).clear_working_directory
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def update_latest_deployed_ref
|
|
26
|
+
# noop: last deployed ref is useless for review stacks
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
model_name.class_eval do
|
|
30
|
+
def route_key
|
|
31
|
+
"stacks"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def singular_route_key
|
|
35
|
+
"stack"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
has_one :pull_request, foreign_key: :stack_id
|
|
40
|
+
|
|
41
|
+
after_commit :emit_added_hooks, on: :create
|
|
42
|
+
after_commit :emit_updated_hooks, on: :update
|
|
43
|
+
after_commit :emit_removed_hooks, on: :destroy
|
|
44
|
+
|
|
45
|
+
state_machine :provision_status, initial: :deprovisioned do
|
|
46
|
+
state :provisioned
|
|
47
|
+
state :provisioning
|
|
48
|
+
state :deprovisioning
|
|
49
|
+
state :deprovisioned
|
|
50
|
+
|
|
51
|
+
event :provision do
|
|
52
|
+
transition deprovisioned: :provisioning
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
event :provision_success do
|
|
56
|
+
transition provisioning: :provisioned
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
event :provision_failure do
|
|
60
|
+
transition provisioning: :deprovisioned
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
event :deprovision do
|
|
64
|
+
transition provisioned: :deprovisioning
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
event :deprovision_success do
|
|
68
|
+
transition deprovisioning: :deprovisioned
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
event :deprovision_failure do
|
|
72
|
+
transition deprovisioning: :provisioned
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
after_transition deprovisioned: :provisioning do |stack, _|
|
|
76
|
+
stack.provisioner.up
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
after_transition provisioned: :deprovisioning do |stack, _|
|
|
80
|
+
stack.provisioner.down
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def env
|
|
85
|
+
return super unless pull_request.present?
|
|
86
|
+
|
|
87
|
+
super
|
|
88
|
+
.merge(
|
|
89
|
+
pull_request
|
|
90
|
+
.labels
|
|
91
|
+
.each_with_object({}) { |label_name, labels| labels[label_name.upcase] = "true" }
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def provisioner
|
|
96
|
+
provisioner_class.new(self)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def provisioner_class
|
|
100
|
+
ProvisioningHandler.fetch(provisioning_handler_name)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def enqueue_for_provisioning
|
|
104
|
+
return if awaiting_provision
|
|
105
|
+
update!(awaiting_provision: true)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def remove_from_provisioning_queue
|
|
109
|
+
return unless awaiting_provision
|
|
110
|
+
update!(awaiting_provision: false)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_partial_path
|
|
114
|
+
"shipit/stacks/stack"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def emit_added_hooks
|
|
118
|
+
Hook.emit(:review_stack, self, action: :added, review_stack: self)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def emit_updated_hooks
|
|
122
|
+
changed = !(previous_changes.keys - %w(updated_at)).empty?
|
|
123
|
+
Hook.emit(:review_stack, self, action: :updated, review_stack: self) if changed
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def emit_removed_hooks
|
|
127
|
+
Hook.emit(:review_stack, self, action: :removed, review_stack: self)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shipit
|
|
4
|
+
class ReviewStackProvisioningQueue
|
|
5
|
+
def self.work
|
|
6
|
+
new.work
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.add(stack)
|
|
10
|
+
stack.enqueue_for_provisioning
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.queued_stacks
|
|
14
|
+
new.queued_stacks
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def work
|
|
18
|
+
queued_stacks.find_each(&method(:provision))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def queued_stacks
|
|
22
|
+
@queued_stacks ||= Shipit::ReviewStack
|
|
23
|
+
.with_provision_status(:deprovisioned)
|
|
24
|
+
.where(awaiting_provision: true)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def provision(stack)
|
|
30
|
+
if stack.provisioner.provision?
|
|
31
|
+
stack.provision
|
|
32
|
+
else
|
|
33
|
+
Rails.logger.info(
|
|
34
|
+
"Putting review ReviewStack<#{stack.id}> back into the provisioning queue - #provision? was falsey."
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/app/models/shipit/stack.rb
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'fileutils'
|
|
2
3
|
|
|
3
4
|
module Shipit
|
|
4
|
-
class Stack <
|
|
5
|
+
class Stack < Record
|
|
5
6
|
module NoDeployedCommit
|
|
6
7
|
extend self
|
|
7
8
|
|
|
@@ -26,14 +27,14 @@ module Shipit
|
|
|
26
27
|
REQUIRED_HOOKS = %i(push status).freeze
|
|
27
28
|
|
|
28
29
|
has_many :commits, dependent: :destroy
|
|
29
|
-
has_many :
|
|
30
|
+
has_many :merge_requests, dependent: :destroy
|
|
30
31
|
has_many :tasks, dependent: :destroy
|
|
31
32
|
has_many :deploys
|
|
32
33
|
has_many :rollbacks
|
|
33
34
|
has_many :deploys_and_rollbacks,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
-> { where(type: %w(Shipit::Deploy Shipit::Rollback)) },
|
|
36
|
+
class_name: 'Task',
|
|
37
|
+
inverse_of: :stack
|
|
37
38
|
has_many :github_hooks, dependent: :destroy, class_name: 'Shipit::GithubHook::Repo'
|
|
38
39
|
has_many :hooks, dependent: :destroy
|
|
39
40
|
has_many :api_clients, dependent: :destroy
|
|
@@ -43,6 +44,22 @@ module Shipit
|
|
|
43
44
|
|
|
44
45
|
scope :not_archived, -> { where(archived_since: nil) }
|
|
45
46
|
|
|
47
|
+
include DeferredTouch
|
|
48
|
+
deferred_touch repository: :updated_at
|
|
49
|
+
|
|
50
|
+
default_scope { preload(:repository) }
|
|
51
|
+
|
|
52
|
+
def env
|
|
53
|
+
{
|
|
54
|
+
'ENVIRONMENT' => environment,
|
|
55
|
+
'LAST_DEPLOYED_SHA' => last_deployed_commit.sha,
|
|
56
|
+
'GITHUB_REPO_OWNER' => repository.owner,
|
|
57
|
+
'GITHUB_REPO_NAME' => repository.name,
|
|
58
|
+
'DEPLOY_URL' => deploy_url,
|
|
59
|
+
'BRANCH' => branch,
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
46
63
|
def repository
|
|
47
64
|
super || build_repository
|
|
48
65
|
end
|
|
@@ -66,19 +83,36 @@ module Shipit
|
|
|
66
83
|
after_commit :emit_merge_status_hooks, on: :update
|
|
67
84
|
after_commit :sync_github, on: :create
|
|
68
85
|
after_commit :schedule_merges_if_necessary, on: :update
|
|
86
|
+
after_commit :sync_github_if_necessary, on: :update
|
|
87
|
+
|
|
88
|
+
def sync_github_if_necessary
|
|
89
|
+
if (archived_since_previously_changed? && archived_since.nil?) || branch_previously_changed?
|
|
90
|
+
sync_github
|
|
91
|
+
end
|
|
92
|
+
end
|
|
69
93
|
|
|
70
94
|
validates :repository, uniqueness: {
|
|
71
95
|
scope: %i(environment), case_sensitive: false,
|
|
72
|
-
message: 'cannot be used more than once with this environment. Check archived stacks.'
|
|
96
|
+
message: 'cannot be used more than once with this environment. Check archived stacks.',
|
|
73
97
|
}
|
|
74
|
-
validates :environment, format: {with: /\A[a-z0-9\-_\:]+\z/}, length: {maximum: ENVIRONMENT_MAX_SIZE}
|
|
75
|
-
validates :deploy_url, format: {with: URI.regexp(%w(http https ssh))}, allow_blank: true
|
|
98
|
+
validates :environment, format: { with: /\A[a-z0-9\-_\:]+\z/ }, length: { maximum: ENVIRONMENT_MAX_SIZE }
|
|
99
|
+
validates :deploy_url, format: { with: URI.regexp(%w(http https ssh)) }, allow_blank: true
|
|
100
|
+
validates :branch, presence: true
|
|
76
101
|
|
|
77
|
-
validates :lock_reason, length: {maximum: 4096}
|
|
102
|
+
validates :lock_reason, length: { maximum: 4096 }
|
|
78
103
|
|
|
79
104
|
serialize :cached_deploy_spec, DeploySpec
|
|
80
|
-
delegate
|
|
81
|
-
|
|
105
|
+
delegate(
|
|
106
|
+
:provisioning_handler_name,
|
|
107
|
+
:find_task_definition,
|
|
108
|
+
:release_status?,
|
|
109
|
+
:release_status_context,
|
|
110
|
+
:release_status_delay,
|
|
111
|
+
:supports_fetch_deployed_revision?,
|
|
112
|
+
:supports_rollback?,
|
|
113
|
+
to: :cached_deploy_spec,
|
|
114
|
+
allow_nil: true
|
|
115
|
+
)
|
|
82
116
|
|
|
83
117
|
def self.refresh_deployed_revisions
|
|
84
118
|
find_each.select(&:supports_fetch_deployed_revision?).each(&:async_refresh_deployed_revision)
|
|
@@ -125,13 +159,29 @@ module Shipit
|
|
|
125
159
|
env: filter_deploy_envs(env&.to_h || {}),
|
|
126
160
|
allow_concurrency: force,
|
|
127
161
|
ignored_safeties: force || !until_commit.deployable?,
|
|
162
|
+
max_retries: retries_on_deploy,
|
|
128
163
|
)
|
|
129
164
|
end
|
|
130
165
|
|
|
131
166
|
def trigger_deploy(*args, **kwargs)
|
|
167
|
+
if changed?
|
|
168
|
+
# If this is the first deploy since the spec changed it's possible the record will be dirty here, meaning we
|
|
169
|
+
# cant lock. In this one case persist the changes, otherwise log a warning and let the lock raise, so we
|
|
170
|
+
# can debug what's going on here. We don't expect anything other than the deploy spec to dirty the model
|
|
171
|
+
# instance, because of how that field is serialised.
|
|
172
|
+
if changes.keys == ['cached_deploy_spec']
|
|
173
|
+
save!
|
|
174
|
+
else
|
|
175
|
+
Rails.logger.warning("#{changes.keys} field(s) were unexpectedly modified on stack #{id} while deploying")
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
132
179
|
run_now = kwargs.delete(:run_now)
|
|
133
|
-
deploy =
|
|
134
|
-
|
|
180
|
+
deploy = with_lock do
|
|
181
|
+
deploy = build_deploy(*args, **kwargs)
|
|
182
|
+
deploy.save!
|
|
183
|
+
deploy
|
|
184
|
+
end
|
|
135
185
|
run_now ? deploy.run_now! : deploy.enqueue
|
|
136
186
|
continuous_delivery_resumed!
|
|
137
187
|
deploy
|
|
@@ -142,7 +192,7 @@ module Shipit
|
|
|
142
192
|
end
|
|
143
193
|
|
|
144
194
|
def continuous_delivery_delayed?
|
|
145
|
-
continuous_delivery_delayed_since? && continuous_deployment? && checks?
|
|
195
|
+
continuous_delivery_delayed_since? && continuous_deployment? && (checks? || deployment_checks?)
|
|
146
196
|
end
|
|
147
197
|
|
|
148
198
|
def continuous_delivery_delayed!
|
|
@@ -150,15 +200,16 @@ module Shipit
|
|
|
150
200
|
end
|
|
151
201
|
|
|
152
202
|
def trigger_continuous_delivery
|
|
203
|
+
return if cached_deploy_spec.blank?
|
|
204
|
+
|
|
153
205
|
commit = next_commit_to_deploy
|
|
154
206
|
|
|
155
|
-
if
|
|
207
|
+
if should_resume_continuous_delivery?(commit)
|
|
156
208
|
continuous_delivery_resumed!
|
|
157
209
|
return
|
|
158
210
|
end
|
|
159
211
|
|
|
160
|
-
if
|
|
161
|
-
commit.recently_pushed?
|
|
212
|
+
if should_delay_continuous_delivery?(commit)
|
|
162
213
|
continuous_delivery_delayed!
|
|
163
214
|
return
|
|
164
215
|
end
|
|
@@ -170,7 +221,7 @@ module Shipit
|
|
|
170
221
|
end
|
|
171
222
|
|
|
172
223
|
def schedule_merges
|
|
173
|
-
|
|
224
|
+
ProcessMergeRequestsJob.perform_later(self)
|
|
174
225
|
end
|
|
175
226
|
|
|
176
227
|
def next_commit_to_deploy
|
|
@@ -190,7 +241,7 @@ module Shipit
|
|
|
190
241
|
def async_refresh_deployed_revision
|
|
191
242
|
async_refresh_deployed_revision!
|
|
192
243
|
rescue => error
|
|
193
|
-
logger.warn
|
|
244
|
+
logger.warn("Failed to dispatch FetchDeployedRevisionJob: [#{error.class.name}] #{error.message}")
|
|
194
245
|
end
|
|
195
246
|
|
|
196
247
|
def async_refresh_deployed_revision!
|
|
@@ -258,8 +309,8 @@ module Shipit
|
|
|
258
309
|
next if commits_to_lock.empty?
|
|
259
310
|
|
|
260
311
|
affected_rows += commits
|
|
261
|
-
|
|
262
|
-
|
|
312
|
+
.where(id: commits_to_lock.map(&:id).uniq)
|
|
313
|
+
.lock_all(revert.author)
|
|
263
314
|
end
|
|
264
315
|
|
|
265
316
|
touch if affected_rows > 1
|
|
@@ -310,7 +361,7 @@ module Shipit
|
|
|
310
361
|
end
|
|
311
362
|
|
|
312
363
|
def deployable?
|
|
313
|
-
!locked? && !active_task?
|
|
364
|
+
!locked? && !active_task? && !awaiting_provision? && deployment_checks_passed?
|
|
314
365
|
end
|
|
315
366
|
|
|
316
367
|
def allows_merges?
|
|
@@ -318,7 +369,7 @@ module Shipit
|
|
|
318
369
|
end
|
|
319
370
|
|
|
320
371
|
def merge_method
|
|
321
|
-
cached_deploy_spec&.
|
|
372
|
+
cached_deploy_spec&.merge_request_merge_method || Shipit.default_merge_method
|
|
322
373
|
end
|
|
323
374
|
|
|
324
375
|
delegate :name=, to: :repository, prefix: :repo
|
|
@@ -329,42 +380,51 @@ module Shipit
|
|
|
329
380
|
delegate :git_url, to: :repository, prefix: :repo
|
|
330
381
|
|
|
331
382
|
def base_path
|
|
332
|
-
Rails.root.join('data', 'stacks', repo_owner, repo_name, environment)
|
|
383
|
+
@base_path ||= Rails.root.join('data', 'stacks', repo_owner, repo_name, environment)
|
|
333
384
|
end
|
|
334
385
|
|
|
335
386
|
def deploys_path
|
|
336
|
-
|
|
387
|
+
@deploys_path ||= base_path.join("deploys")
|
|
337
388
|
end
|
|
338
389
|
|
|
339
390
|
def git_path
|
|
340
|
-
|
|
391
|
+
@git_path ||= base_path.join("git")
|
|
341
392
|
end
|
|
342
393
|
|
|
343
394
|
def acquire_git_cache_lock(timeout: 15, &block)
|
|
344
|
-
Flock.new(git_path.to_s + '.lock')
|
|
395
|
+
@git_cache_lock ||= Flock.new(git_path.to_s + '.lock')
|
|
396
|
+
@git_cache_lock.lock(timeout: timeout, &block)
|
|
345
397
|
end
|
|
346
398
|
|
|
347
399
|
def clear_git_cache!
|
|
348
400
|
tmp_path = "#{git_path}-#{SecureRandom.hex}"
|
|
349
|
-
return unless
|
|
401
|
+
return unless git_path.exist?
|
|
350
402
|
acquire_git_cache_lock do
|
|
351
|
-
|
|
403
|
+
git_path.rename(tmp_path)
|
|
352
404
|
end
|
|
353
405
|
FileUtils.rm_rf(tmp_path)
|
|
354
406
|
end
|
|
355
407
|
|
|
356
408
|
def github_repo_name
|
|
357
|
-
|
|
409
|
+
repository.github_repo_name
|
|
358
410
|
end
|
|
359
411
|
|
|
360
412
|
def github_commits
|
|
361
413
|
handle_github_redirections do
|
|
362
|
-
|
|
414
|
+
github_api.commits(github_repo_name, sha: branch)
|
|
363
415
|
end
|
|
364
416
|
rescue Octokit::Conflict
|
|
365
417
|
[] # Repository is empty...
|
|
366
418
|
end
|
|
367
419
|
|
|
420
|
+
def github_api
|
|
421
|
+
github_app.api
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
def github_app
|
|
425
|
+
Shipit.github(organization: repository.owner)
|
|
426
|
+
end
|
|
427
|
+
|
|
368
428
|
def handle_github_redirections
|
|
369
429
|
# https://developer.github.com/v3/#http-redirects
|
|
370
430
|
resource = yield
|
|
@@ -377,9 +437,9 @@ module Shipit
|
|
|
377
437
|
end
|
|
378
438
|
|
|
379
439
|
def refresh_repository!
|
|
380
|
-
resource =
|
|
440
|
+
resource = github_api.repo(github_repo_name)
|
|
381
441
|
if resource.try(:message) == 'Moved Permanently'
|
|
382
|
-
resource =
|
|
442
|
+
resource = github_api.get(resource.url)
|
|
383
443
|
end
|
|
384
444
|
repository.update!(owner: resource.owner.login, name: resource.name)
|
|
385
445
|
end
|
|
@@ -398,7 +458,7 @@ module Shipit
|
|
|
398
458
|
end
|
|
399
459
|
|
|
400
460
|
def lock(reason, user)
|
|
401
|
-
params = {lock_reason: reason, lock_author: user}
|
|
461
|
+
params = { lock_reason: reason, lock_author: user }
|
|
402
462
|
update!(params)
|
|
403
463
|
end
|
|
404
464
|
|
|
@@ -444,8 +504,9 @@ module Shipit
|
|
|
444
504
|
end
|
|
445
505
|
|
|
446
506
|
delegate :plugins, :task_definitions, :hidden_statuses, :required_statuses, :soft_failing_statuses,
|
|
447
|
-
|
|
448
|
-
|
|
507
|
+
:blocking_statuses, :deploy_variables, :filter_task_envs, :filter_deploy_envs,
|
|
508
|
+
:maximum_commits_per_deploy, :pause_between_deploys, :retries_on_deploy, :retries_on_rollback,
|
|
509
|
+
to: :cached_deploy_spec
|
|
449
510
|
|
|
450
511
|
def monitoring?
|
|
451
512
|
monitoring.present?
|
|
@@ -470,13 +531,15 @@ module Shipit
|
|
|
470
531
|
end
|
|
471
532
|
|
|
472
533
|
def update_latest_deployed_ref
|
|
473
|
-
|
|
534
|
+
if Shipit.update_latest_deployed_ref
|
|
535
|
+
UpdateGithubLastDeployedRefJob.perform_later(self)
|
|
536
|
+
end
|
|
474
537
|
end
|
|
475
538
|
|
|
476
539
|
def broadcast_update
|
|
477
540
|
Pubsubstub.publish(
|
|
478
541
|
"stack.#{id}",
|
|
479
|
-
{id: id, updated_at: updated_at}.to_json,
|
|
542
|
+
{ id: id, updated_at: updated_at }.to_json,
|
|
480
543
|
name: 'update',
|
|
481
544
|
)
|
|
482
545
|
end
|
|
@@ -528,19 +591,38 @@ module Shipit
|
|
|
528
591
|
GithubSyncJob.perform_later(stack_id: id)
|
|
529
592
|
end
|
|
530
593
|
|
|
531
|
-
|
|
594
|
+
def links
|
|
595
|
+
links_spec = cached_deploy_spec&.links || {}
|
|
596
|
+
context = EnvironmentVariables.with(env)
|
|
532
597
|
|
|
533
|
-
|
|
534
|
-
remove_instance_variable(:@active_task) if defined?(@active_task)
|
|
598
|
+
links_spec.transform_values { |url| context.interpolate(url) }
|
|
535
599
|
end
|
|
536
600
|
|
|
537
601
|
def clear_local_files
|
|
538
602
|
FileUtils.rm_rf(base_path.to_s)
|
|
539
603
|
end
|
|
540
604
|
|
|
605
|
+
def deployment_checks_passed?
|
|
606
|
+
return true unless deployment_checks?
|
|
607
|
+
|
|
608
|
+
Shipit.deployment_checks.call(self)
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
private
|
|
612
|
+
|
|
613
|
+
def clear_cache
|
|
614
|
+
remove_instance_variable(:@active_task) if defined?(@active_task)
|
|
615
|
+
end
|
|
616
|
+
|
|
541
617
|
def update_defaults
|
|
542
618
|
self.environment = 'production' if environment.blank?
|
|
543
|
-
self.branch =
|
|
619
|
+
self.branch = default_branch_name if branch.blank?
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
def default_branch_name
|
|
623
|
+
Shipit.github.api.repo(github_repo_name).default_branch
|
|
624
|
+
rescue Octokit::NotFound, Octokit::InvalidRepository
|
|
625
|
+
nil
|
|
544
626
|
end
|
|
545
627
|
|
|
546
628
|
def set_locked_since
|
|
@@ -554,7 +636,7 @@ module Shipit
|
|
|
554
636
|
end
|
|
555
637
|
|
|
556
638
|
def schedule_merges_if_necessary
|
|
557
|
-
if
|
|
639
|
+
if lock_reason_previously_changed? && lock_reason.blank?
|
|
558
640
|
schedule_merges
|
|
559
641
|
end
|
|
560
642
|
end
|
|
@@ -563,7 +645,7 @@ module Shipit
|
|
|
563
645
|
return unless previous_changes.include?('lock_reason')
|
|
564
646
|
|
|
565
647
|
lock_details = if previous_changes['lock_reason'].last.blank?
|
|
566
|
-
{from: previous_changes['locked_since'].first, until: Time.zone.now}
|
|
648
|
+
{ from: previous_changes['locked_since'].first, until: Time.zone.now }
|
|
567
649
|
end
|
|
568
650
|
|
|
569
651
|
Hook.emit(:lock, self, locked: locked?, lock_details: lock_details, stack: self)
|
|
@@ -589,5 +671,23 @@ module Shipit
|
|
|
589
671
|
def ci_enabled_cache_key
|
|
590
672
|
"stacks:#{id}:ci_enabled"
|
|
591
673
|
end
|
|
674
|
+
|
|
675
|
+
def should_resume_continuous_delivery?(commit)
|
|
676
|
+
(deployment_checks_passed? && !deployable?) ||
|
|
677
|
+
deployed_too_recently? ||
|
|
678
|
+
commit.nil? ||
|
|
679
|
+
commit.deployed?
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
def should_delay_continuous_delivery?(commit)
|
|
683
|
+
commit.deploy_failed? ||
|
|
684
|
+
(checks? && !EphemeralCommitChecks.new(commit).run.success?) ||
|
|
685
|
+
!deployment_checks_passed? ||
|
|
686
|
+
commit.recently_pushed?
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
def deployment_checks?
|
|
690
|
+
Shipit.deployment_checks.present?
|
|
691
|
+
end
|
|
592
692
|
end
|
|
593
693
|
end
|