shipit-engine 0.38.0 → 0.40.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 +48 -4
- data/Rakefile +2 -1
- data/app/assets/javascripts/shipit/continuous_delivery_schedule.js.coffee +15 -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 +1 -0
- data/app/controllers/concerns/shipit/authentication.rb +1 -0
- data/app/controllers/concerns/shipit/pagination.rb +3 -2
- data/app/controllers/shipit/api/base_controller.rb +12 -10
- data/app/controllers/shipit/api/ccmenu_controller.rb +2 -1
- data/app/controllers/shipit/api/commits_controller.rb +2 -3
- data/app/controllers/shipit/api/deploys_controller.rb +6 -1
- data/app/controllers/shipit/api/hooks_controller.rb +4 -3
- data/app/controllers/shipit/api/locks_controller.rb +1 -0
- data/app/controllers/shipit/api/merge_requests_controller.rb +6 -5
- data/app/controllers/shipit/api/outputs_controller.rb +1 -0
- data/app/controllers/shipit/api/release_statuses_controller.rb +2 -1
- data/app/controllers/shipit/api/rollbacks_controller.rb +1 -0
- data/app/controllers/shipit/api/stacks_controller.rb +15 -14
- data/app/controllers/shipit/api/tasks_controller.rb +6 -5
- data/app/controllers/shipit/api_clients_controller.rb +6 -7
- data/app/controllers/shipit/ccmenu_url_controller.rb +3 -2
- data/app/controllers/shipit/commit_checks_controller.rb +2 -1
- data/app/controllers/shipit/commits_controller.rb +1 -0
- data/app/controllers/shipit/continuous_delivery_schedules_controller.rb +42 -0
- data/app/controllers/shipit/deploys_controller.rb +6 -5
- data/app/controllers/shipit/github_authentication_controller.rb +6 -0
- data/app/controllers/shipit/merge_requests_controller.rb +1 -0
- data/app/controllers/shipit/merge_status_controller.rb +30 -26
- data/app/controllers/shipit/release_statuses_controller.rb +1 -0
- data/app/controllers/shipit/repositories_controller.rb +4 -7
- data/app/controllers/shipit/rollbacks_controller.rb +2 -1
- data/app/controllers/shipit/shipit_controller.rb +1 -0
- data/app/controllers/shipit/stacks_controller.rb +27 -31
- data/app/controllers/shipit/status_controller.rb +1 -0
- data/app/controllers/shipit/tasks_controller.rb +3 -1
- data/app/controllers/shipit/webhooks_controller.rb +2 -1
- data/app/helpers/shipit/api_clients_helper.rb +1 -0
- data/app/helpers/shipit/chunks_helper.rb +3 -1
- data/app/helpers/shipit/deploys_helper.rb +7 -3
- data/app/helpers/shipit/github_url_helper.rb +5 -4
- data/app/helpers/shipit/merge_status_helper.rb +1 -0
- data/app/helpers/shipit/shipit_helper.rb +11 -10
- data/app/helpers/shipit/stacks_helper.rb +10 -11
- data/app/helpers/shipit/tasks_helper.rb +2 -1
- data/app/jobs/shipit/background_job/unique.rb +3 -2
- data/app/jobs/shipit/background_job.rb +9 -1
- data/app/jobs/shipit/cache_deploy_spec_job.rb +2 -1
- data/app/jobs/shipit/chunk_rollup_job.rb +1 -0
- data/app/jobs/shipit/clear_git_cache_job.rb +1 -0
- data/app/jobs/shipit/continuous_delivery_job.rb +5 -0
- data/app/jobs/shipit/create_on_github_job.rb +1 -0
- data/app/jobs/shipit/create_release_statuses_job.rb +2 -0
- data/app/jobs/shipit/deferred_touch_job.rb +1 -0
- data/app/jobs/shipit/deliver_hook_job.rb +1 -0
- data/app/jobs/shipit/destroy_job.rb +1 -0
- data/app/jobs/shipit/destroy_repository_job.rb +1 -0
- data/app/jobs/shipit/destroy_stack_job.rb +36 -15
- data/app/jobs/shipit/emit_event_job.rb +1 -0
- 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 +4 -2
- 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 +1 -0
- data/app/jobs/shipit/process_merge_requests_job.rb +2 -0
- data/app/jobs/shipit/purge_old_deliveries_job.rb +1 -0
- data/app/jobs/shipit/reap_dead_tasks_job.rb +1 -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 +1 -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 +6 -7
- data/app/models/concerns/shipit/deferred_touch.rb +5 -2
- data/app/models/shipit/anonymous_user.rb +4 -5
- data/app/models/shipit/api_client.rb +5 -3
- data/app/models/shipit/application_record.rb +1 -0
- data/app/models/shipit/check_run.rb +7 -6
- data/app/models/shipit/command_line_user.rb +4 -5
- data/app/models/shipit/commit.rb +46 -32
- data/app/models/shipit/commit_checks.rb +4 -2
- data/app/models/shipit/commit_deployment.rb +7 -5
- data/app/models/shipit/commit_deployment_status.rb +5 -3
- data/app/models/shipit/commit_message.rb +2 -0
- data/app/models/shipit/continuous_delivery_schedule.rb +84 -0
- data/app/models/shipit/delivery.rb +5 -4
- data/app/models/shipit/deploy.rb +46 -26
- data/app/models/shipit/deploy_spec/bundler_discovery.rb +3 -1
- data/app/models/shipit/deploy_spec/capistrano_discovery.rb +1 -0
- data/app/models/shipit/deploy_spec/file_system.rb +48 -17
- data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +4 -3
- data/app/models/shipit/deploy_spec/lerna_discovery.rb +32 -31
- data/app/models/shipit/deploy_spec/npm_discovery.rb +18 -13
- data/app/models/shipit/deploy_spec/pypi_discovery.rb +5 -4
- data/app/models/shipit/deploy_spec/rubygems_discovery.rb +1 -0
- data/app/models/shipit/deploy_spec.rb +25 -30
- data/app/models/shipit/deploy_stats.rb +6 -1
- data/app/models/shipit/duration.rb +5 -3
- data/app/models/shipit/ephemeral_commit_checks.rb +8 -7
- data/app/models/shipit/github_hook.rb +1 -0
- data/app/models/shipit/github_status.rb +1 -0
- data/app/models/shipit/hook.rb +9 -7
- data/app/models/shipit/membership.rb +1 -0
- data/app/models/shipit/merge_request.rb +26 -16
- data/app/models/shipit/output_chunk.rb +1 -0
- data/app/models/shipit/provisioning_handler.rb +1 -0
- data/app/models/shipit/pull_request.rb +2 -2
- data/app/models/shipit/record.rb +1 -0
- data/app/models/shipit/release_status.rb +4 -3
- data/app/models/shipit/repository.rb +12 -11
- data/app/models/shipit/review_stack.rb +3 -1
- data/app/models/shipit/review_stack_provisioning_queue.rb +2 -2
- data/app/models/shipit/rollback.rb +2 -0
- data/app/models/shipit/stack.rb +71 -60
- data/app/models/shipit/status/common.rb +1 -0
- data/app/models/shipit/status/group.rb +5 -3
- data/app/models/shipit/status/missing.rb +2 -1
- data/app/models/shipit/status/unknown.rb +1 -0
- data/app/models/shipit/status.rb +5 -4
- data/app/models/shipit/task.rb +40 -31
- data/app/models/shipit/task_definition.rb +10 -7
- data/app/models/shipit/task_execution_strategy/default.rb +13 -13
- data/app/models/shipit/team.rb +13 -12
- data/app/models/shipit/undeployed_commit.rb +8 -3
- data/app/models/shipit/unlimited_api_client.rb +2 -2
- data/app/models/shipit/user.rb +23 -16
- data/app/models/shipit/variable_definition.rb +2 -1
- 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 +10 -10
- data/app/models/shipit/webhooks/handlers/pull_request/closed_handler.rb +1 -1
- data/app/models/shipit/webhooks/handlers/pull_request/edited_handler.rb +10 -10
- data/app/models/shipit/webhooks/handlers/pull_request/label_capturing_handler.rb +2 -2
- data/app/models/shipit/webhooks/handlers/pull_request/labeled_handler.rb +2 -2
- data/app/models/shipit/webhooks/handlers/pull_request/reopened_handler.rb +1 -1
- data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +3 -3
- data/app/models/shipit/webhooks/handlers/pull_request/unlabeled_handler.rb +1 -1
- data/app/models/shipit/webhooks/handlers/push_handler.rb +2 -1
- data/app/models/shipit/webhooks/handlers/status_handler.rb +1 -0
- data/app/models/shipit/webhooks.rb +3 -2
- 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 +2 -1
- data/app/serializers/shipit/deploy_serializer.rb +1 -0
- data/app/serializers/shipit/hook_serializer.rb +1 -0
- data/app/serializers/shipit/merge_request_serializer.rb +2 -1
- 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 +4 -3
- data/app/serializers/shipit/tail_task_serializer.rb +4 -1
- data/app/serializers/shipit/task_serializer.rb +1 -0
- data/app/serializers/shipit/user_serializer.rb +1 -0
- data/app/validators/ascii_only_validator.rb +4 -3
- data/app/validators/subset_validator.rb +1 -0
- data/app/views/shipit/_variables.html.erb +1 -1
- data/app/views/shipit/ccmenu/project.xml.builder +2 -1
- data/app/views/shipit/continuous_delivery_schedules/show.html.erb +59 -0
- data/app/views/shipit/merge_status/failure.html.erb +1 -1
- data/app/views/shipit/missing_settings.html.erb +1 -1
- data/app/views/shipit/stacks/_settings_form.erb +1 -0
- data/config/initializers/inflections.rb +1 -0
- data/config/locales/en.yml +1 -0
- data/config/routes.rb +21 -18
- data/config/secrets.development.example.yml +1 -1
- data/config/secrets.development.shopify.yml +1 -1
- data/db/migrate/20240821003007_add_continuous_delivery_schedules.rb +13 -0
- data/db/migrate/20250207203053_embiggen_github_ids.rb +8 -0
- data/lib/shipit/cast_value.rb +1 -0
- data/lib/shipit/command.rb +29 -9
- data/lib/shipit/commands.rb +4 -2
- data/lib/shipit/csv_serializer.rb +3 -0
- data/lib/shipit/deploy_commands.rb +2 -1
- data/lib/shipit/engine.rb +6 -5
- data/lib/shipit/environment_variables.rb +2 -0
- data/lib/shipit/first_parent_commits_iterator.rb +2 -3
- data/lib/shipit/flock.rb +11 -9
- data/lib/shipit/github_app.rb +14 -16
- 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 +2 -3
- data/lib/shipit/octokit_iterator.rb +2 -0
- data/lib/shipit/paginator.rb +1 -0
- data/lib/shipit/rollback_commands.rb +2 -1
- data/lib/shipit/same_site_cookie_middleware.rb +1 -0
- data/lib/shipit/simple_message_verifier.rb +1 -0
- data/lib/shipit/stack_commands.rb +35 -27
- data/lib/shipit/stat.rb +1 -0
- data/lib/shipit/task_commands.rb +7 -6
- data/lib/shipit/version.rb +2 -1
- data/lib/shipit.rb +30 -17
- data/lib/tasks/cron.rake +2 -1
- data/lib/tasks/dev.rake +3 -2
- data/lib/tasks/shipit.rake +3 -2
- data/lib/tasks/teams.rake +3 -2
- data/test/controllers/api/base_controller_test.rb +1 -0
- data/test/controllers/api/ccmenu_controller_test.rb +4 -3
- data/test/controllers/api/commits_controller_test.rb +1 -0
- data/test/controllers/api/deploys_controller_test.rb +26 -1
- data/test/controllers/api/hooks_controller_test.rb +6 -5
- data/test/controllers/api/locks_controller_test.rb +1 -0
- data/test/controllers/api/merge_requests_controller_test.rb +1 -0
- data/test/controllers/api/outputs_controller_test.rb +1 -0
- data/test/controllers/api/release_statuses_controller_test.rb +4 -3
- data/test/controllers/api/rollback_controller_test.rb +3 -2
- data/test/controllers/api/stacks_controller_test.rb +13 -12
- data/test/controllers/api/tasks_controller_test.rb +7 -6
- data/test/controllers/api_clients_controller_test.rb +10 -10
- data/test/controllers/ccmenu_controller_test.rb +1 -0
- data/test/controllers/commit_checks_controller_test.rb +1 -0
- data/test/controllers/commits_controller_test.rb +9 -8
- data/test/controllers/continuous_delivery_schedules_controller_test.rb +66 -0
- data/test/controllers/deploys_controller_test.rb +4 -2
- data/test/controllers/github_authentication_controller_test.rb +6 -4
- data/test/controllers/merge_requests_controller_test.rb +1 -0
- data/test/controllers/merge_status_controller_test.rb +5 -4
- data/test/controllers/release_statuses_controller_test.rb +1 -0
- data/test/controllers/repositories_controller_test.rb +6 -5
- data/test/controllers/rollbacks_controller_test.rb +3 -2
- data/test/controllers/stacks_controller_test.rb +8 -6
- data/test/controllers/status_controller_test.rb +1 -0
- data/test/controllers/tasks_controller_test.rb +13 -5
- data/test/controllers/webhooks_controller_test.rb +10 -9
- data/test/dummy/config/application.rb +2 -1
- data/test/dummy/config/initializers/0_load_development_secrets.rb +2 -2
- data/test/dummy/config/secrets.development.json +3 -0
- data/test/dummy/config/secrets.test.json +21 -0
- data/test/dummy/db/schema.rb +33 -6
- data/test/fixtures/shipit/commits.yml +7 -7
- data/test/fixtures/shipit/stacks.yml +4 -10
- data/test/fixtures/shipit/tasks.yml +3 -3
- data/test/helpers/api_helper.rb +2 -3
- data/test/helpers/fixture_aliases_helper.rb +1 -0
- data/test/helpers/hooks_helper.rb +1 -0
- data/test/helpers/json_helper.rb +4 -3
- data/test/helpers/links_helper.rb +2 -1
- data/test/helpers/payloads_helper.rb +1 -0
- data/test/helpers/queries_helper.rb +4 -3
- data/test/jobs/cache_deploy_spec_job_test.rb +3 -2
- data/test/jobs/chunk_rollup_job_test.rb +3 -2
- data/test/jobs/deliver_hook_job_test.rb +1 -0
- data/test/jobs/destroy_repository_job_test.rb +1 -0
- data/test/jobs/destroy_stack_job_test.rb +12 -0
- data/test/jobs/emit_event_job_test.rb +1 -0
- 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 +22 -21
- data/test/jobs/mark_deploy_healthy_job_test.rb +1 -0
- data/test/jobs/perform_task_job_test.rb +3 -3
- data/test/jobs/process_merge_requests_job_test.rb +7 -6
- data/test/jobs/purge_old_deliveries_job_test.rb +1 -0
- data/test/jobs/reap_dead_tasks_job_test.rb +1 -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/shipit/background_job_test.rb +35 -0
- data/test/jobs/shipit/continuous_delivery_job_test.rb +31 -0
- data/test/jobs/unique_job_test.rb +3 -1
- data/test/jobs/update_github_last_deployed_ref_job_test.rb +1 -0
- data/test/middleware/same_site_cookie_middleware_test.rb +2 -2
- data/test/models/api_client_test.rb +1 -0
- data/test/models/commit_checks_test.rb +2 -1
- data/test/models/commit_deployment_status_test.rb +2 -2
- data/test/models/commit_deployment_test.rb +4 -3
- data/test/models/commits_test.rb +72 -70
- data/test/models/delivery_test.rb +3 -2
- data/test/models/deploy_spec_test.rb +113 -109
- data/test/models/deploy_stats_test.rb +1 -0
- data/test/models/deploys_test.rb +65 -56
- data/test/models/duration_test.rb +1 -1
- data/test/models/github_hook_test.rb +1 -0
- data/test/models/hook_test.rb +7 -4
- data/test/models/membership_test.rb +1 -0
- data/test/models/merge_request_test.rb +26 -20
- data/test/models/release_statuses_test.rb +2 -1
- data/test/models/rollbacks_test.rb +4 -3
- data/test/models/shipit/check_run_test.rb +16 -15
- data/test/models/shipit/continuous_delivery_schedule_test.rb +109 -0
- data/test/models/shipit/deploy_spec/file_system_test.rb +54 -10
- data/test/models/shipit/pull_request_test.rb +9 -9
- data/test/models/shipit/repository_test.rb +3 -2
- data/test/models/shipit/review_stack_provisioning_queue_test.rb +2 -2
- data/test/models/shipit/{stacks_test.rb → stack_test.rb} +48 -34
- data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +36 -34
- data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +28 -28
- data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +42 -42
- data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +33 -33
- data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +37 -37
- data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +1 -1
- data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +44 -42
- data/test/models/shipit/webhooks/handlers_test.rb +1 -0
- data/test/models/status/group_test.rb +3 -2
- data/test/models/status/missing_test.rb +1 -0
- data/test/models/status_test.rb +2 -1
- data/test/models/task_definitions_test.rb +7 -6
- data/test/models/tasks_test.rb +5 -4
- data/test/models/team_test.rb +5 -4
- data/test/models/undeployed_commits_test.rb +10 -9
- data/test/models/users_test.rb +29 -20
- data/test/test_command_integration.rb +1 -1
- data/test/test_helper.rb +12 -10
- data/test/unit/anonymous_user_serializer_test.rb +1 -0
- data/test/unit/command_test.rb +10 -1
- data/test/unit/commands_test.rb +1 -0
- data/test/unit/commit_serializer_test.rb +1 -0
- data/test/unit/csv_serializer_test.rb +3 -2
- data/test/unit/deploy_commands_test.rb +33 -23
- data/test/unit/deploy_serializer_test.rb +1 -0
- data/test/unit/environment_variables_test.rb +2 -1
- data/test/unit/github_app_test.rb +11 -10
- data/test/unit/github_apps_test.rb +19 -18
- data/test/unit/github_url_helper_test.rb +1 -0
- data/test/unit/line_buffer_test.rb +1 -1
- data/test/unit/rollback_commands_test.rb +2 -1
- data/test/unit/shipit_helper_test.rb +1 -0
- data/test/unit/shipit_test.rb +47 -1
- data/test/unit/user_serializer_test.rb +1 -0
- data/test/unit/variable_definition_test.rb +4 -3
- metadata +61 -47
data/app/models/shipit/stack.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'fileutils'
|
3
4
|
|
4
5
|
module Shipit
|
@@ -24,7 +25,7 @@ module Shipit
|
|
24
25
|
end
|
25
26
|
|
26
27
|
ENVIRONMENT_MAX_SIZE = 50
|
27
|
-
REQUIRED_HOOKS = %i
|
28
|
+
REQUIRED_HOOKS = %i[push status].freeze
|
28
29
|
|
29
30
|
has_many :commits, dependent: :destroy
|
30
31
|
has_many :merge_requests, dependent: :destroy
|
@@ -32,12 +33,13 @@ module Shipit
|
|
32
33
|
has_many :deploys
|
33
34
|
has_many :rollbacks
|
34
35
|
has_many :deploys_and_rollbacks,
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
-> { where(type: %w[Shipit::Deploy Shipit::Rollback]) },
|
37
|
+
class_name: 'Task',
|
38
|
+
inverse_of: :stack
|
38
39
|
has_many :github_hooks, dependent: :destroy, class_name: 'Shipit::GithubHook::Repo'
|
39
40
|
has_many :hooks, dependent: :destroy
|
40
41
|
has_many :api_clients, dependent: :destroy
|
42
|
+
has_one :continuous_delivery_schedule, dependent: :destroy
|
41
43
|
belongs_to :lock_author, class_name: :User, optional: true
|
42
44
|
belongs_to :repository
|
43
45
|
validates_associated :repository
|
@@ -56,7 +58,7 @@ module Shipit
|
|
56
58
|
'GITHUB_REPO_OWNER' => repository.owner,
|
57
59
|
'GITHUB_REPO_NAME' => repository.name,
|
58
60
|
'DEPLOY_URL' => deploy_url,
|
59
|
-
'BRANCH' => branch
|
61
|
+
'BRANCH' => branch
|
60
62
|
}
|
61
63
|
end
|
62
64
|
|
@@ -86,22 +88,22 @@ module Shipit
|
|
86
88
|
after_commit :sync_github_if_necessary, on: :update
|
87
89
|
|
88
90
|
def sync_github_if_necessary
|
89
|
-
|
90
|
-
|
91
|
-
|
91
|
+
return unless (archived_since_previously_changed? && archived_since.nil?) || branch_previously_changed?
|
92
|
+
|
93
|
+
sync_github
|
92
94
|
end
|
93
95
|
|
94
96
|
validates :repository, uniqueness: {
|
95
|
-
scope: %i
|
96
|
-
message: 'cannot be used more than once with this environment. Check archived stacks.'
|
97
|
+
scope: %i[environment], case_sensitive: false,
|
98
|
+
message: 'cannot be used more than once with this environment. Check archived stacks.'
|
97
99
|
}
|
98
|
-
validates :environment, format: { with: /\A[a-z0-9\-_
|
99
|
-
validates :deploy_url, format: { with: URI.
|
100
|
+
validates :environment, format: { with: /\A[a-z0-9\-_:]+\z/ }, length: { maximum: ENVIRONMENT_MAX_SIZE }
|
101
|
+
validates :deploy_url, format: { with: URI::DEFAULT_PARSER.make_regexp(%w[http https ssh]) }, allow_blank: true
|
100
102
|
validates :branch, presence: true
|
101
103
|
|
102
104
|
validates :lock_reason, length: { maximum: 4096 }
|
103
105
|
|
104
|
-
serialize :cached_deploy_spec, DeploySpec
|
106
|
+
serialize :cached_deploy_spec, coder: DeploySpec
|
105
107
|
delegate(
|
106
108
|
:provisioning_handler_name,
|
107
109
|
:find_task_definition,
|
@@ -130,7 +132,7 @@ module Shipit
|
|
130
132
|
|
131
133
|
def trigger_task(definition_id, user, env: nil, force: false)
|
132
134
|
definition = find_task_definition(definition_id)
|
133
|
-
env = env
|
135
|
+
env = env.to_h
|
134
136
|
|
135
137
|
definition.variables_with_defaults.each do |variable|
|
136
138
|
env[variable.name] ||= variable.default
|
@@ -139,27 +141,27 @@ module Shipit
|
|
139
141
|
commit = last_deployed_commit.presence || commits.first
|
140
142
|
task = tasks.create(
|
141
143
|
user_id: user.id,
|
142
|
-
definition
|
144
|
+
definition:,
|
143
145
|
until_commit_id: commit.id,
|
144
146
|
since_commit_id: commit.id,
|
145
147
|
env: definition.filter_envs(env),
|
146
148
|
allow_concurrency: definition.allow_concurrency? || force,
|
147
|
-
ignored_safeties: force
|
149
|
+
ignored_safeties: force
|
148
150
|
)
|
149
151
|
task.enqueue
|
150
152
|
task
|
151
153
|
end
|
152
154
|
|
153
|
-
def build_deploy(until_commit, user, env: nil, force: false)
|
155
|
+
def build_deploy(until_commit, user, env: nil, force: false, allow_concurrency: force)
|
154
156
|
since_commit = last_deployed_commit.presence || commits.first
|
155
157
|
deploys.build(
|
156
158
|
user_id: user.id,
|
157
|
-
until_commit
|
158
|
-
since_commit
|
159
|
-
env: filter_deploy_envs(env
|
160
|
-
allow_concurrency
|
159
|
+
until_commit:,
|
160
|
+
since_commit:,
|
161
|
+
env: filter_deploy_envs(env.to_h),
|
162
|
+
allow_concurrency:,
|
161
163
|
ignored_safeties: force || !until_commit.deployable?,
|
162
|
-
max_retries: retries_on_deploy
|
164
|
+
max_retries: retries_on_deploy
|
163
165
|
)
|
164
166
|
end
|
165
167
|
|
@@ -226,22 +228,25 @@ module Shipit
|
|
226
228
|
|
227
229
|
def next_commit_to_deploy
|
228
230
|
commits_to_deploy = commits.order(id: :asc).newer_than(last_deployed_commit).reachable.preload(:statuses)
|
229
|
-
|
230
|
-
|
231
|
+
if maximum_commits_per_deploy
|
232
|
+
commits_with_max_applied = commits_to_deploy.limit(maximum_commits_per_deploy)
|
233
|
+
deployable_commits(commits_with_max_applied) || deployable_commits(commits_to_deploy)
|
234
|
+
else
|
235
|
+
deployable_commits(commits_to_deploy)
|
236
|
+
end
|
231
237
|
end
|
232
238
|
|
233
239
|
def deployed_too_recently?
|
234
|
-
|
235
|
-
|
240
|
+
return unless task = last_active_task
|
241
|
+
return true if task.validating?
|
236
242
|
|
237
|
-
|
238
|
-
end
|
243
|
+
task.ended_at? && (task.ended_at + pause_between_deploys).future?
|
239
244
|
end
|
240
245
|
|
241
246
|
def async_refresh_deployed_revision
|
242
247
|
async_refresh_deployed_revision!
|
243
|
-
rescue =>
|
244
|
-
logger.warn("Failed to dispatch FetchDeployedRevisionJob: [#{
|
248
|
+
rescue StandardError => e
|
249
|
+
logger.warn("Failed to dispatch FetchDeployedRevisionJob: [#{e.class.name}] #{e.message}")
|
245
250
|
end
|
246
251
|
|
247
252
|
def async_refresh_deployed_revision!
|
@@ -263,7 +268,7 @@ module Shipit
|
|
263
268
|
deploys.create!(
|
264
269
|
until_commit: actual_deployed_commit,
|
265
270
|
since_commit: last_deployed_commit.presence || commits.first,
|
266
|
-
status: 'success'
|
271
|
+
status: 'success'
|
267
272
|
)
|
268
273
|
end
|
269
274
|
end
|
@@ -274,8 +279,9 @@ module Shipit
|
|
274
279
|
|
275
280
|
def merge_status(backlog_leniency_factor: 2.0)
|
276
281
|
return 'locked' if locked?
|
277
|
-
return 'failure' if %w
|
278
|
-
return 'backlogged' if backlogged?(backlog_leniency_factor:
|
282
|
+
return 'failure' if %w[failure error].freeze.include?(branch_status)
|
283
|
+
return 'backlogged' if backlogged?(backlog_leniency_factor:)
|
284
|
+
|
279
285
|
'success'
|
280
286
|
end
|
281
287
|
|
@@ -286,13 +292,14 @@ module Shipit
|
|
286
292
|
def branch_status
|
287
293
|
undeployed_commits.each do |commit|
|
288
294
|
state = commit.status.simple_state
|
289
|
-
return state unless %w
|
295
|
+
return state unless %w[pending unknown missing].freeze.include?(state)
|
290
296
|
end
|
291
297
|
'pending'
|
292
298
|
end
|
293
299
|
|
294
300
|
def status
|
295
301
|
return :deploying if active_task?
|
302
|
+
|
296
303
|
:default
|
297
304
|
end
|
298
305
|
|
@@ -309,8 +316,8 @@ module Shipit
|
|
309
316
|
next if commits_to_lock.empty?
|
310
317
|
|
311
318
|
affected_rows += commits
|
312
|
-
|
313
|
-
|
319
|
+
.where(id: commits_to_lock.map(&:id).uniq)
|
320
|
+
.lock_all(revert.author)
|
314
321
|
end
|
315
322
|
|
316
323
|
touch if affected_rows > 1
|
@@ -392,13 +399,14 @@ module Shipit
|
|
392
399
|
end
|
393
400
|
|
394
401
|
def acquire_git_cache_lock(timeout: 15, &block)
|
395
|
-
@git_cache_lock ||= Flock.new(git_path.
|
396
|
-
@git_cache_lock.lock(timeout
|
402
|
+
@git_cache_lock ||= Flock.new("#{git_path}.lock")
|
403
|
+
@git_cache_lock.lock(timeout:, &block)
|
397
404
|
end
|
398
405
|
|
399
406
|
def clear_git_cache!
|
400
407
|
tmp_path = "#{git_path}-#{SecureRandom.hex}"
|
401
408
|
return unless git_path.exist?
|
409
|
+
|
402
410
|
acquire_git_cache_lock do
|
403
411
|
git_path.rename(tmp_path)
|
404
412
|
end
|
@@ -438,9 +446,7 @@ module Shipit
|
|
438
446
|
|
439
447
|
def refresh_repository!
|
440
448
|
resource = github_api.repo(github_repo_name)
|
441
|
-
if resource.try(:message) == 'Moved Permanently'
|
442
|
-
resource = github_api.get(resource.url)
|
443
|
-
end
|
449
|
+
resource = github_api.get(resource.url) if resource.try(:message) == 'Moved Permanently'
|
444
450
|
repository.update!(owner: resource.owner.login, name: resource.name)
|
445
451
|
end
|
446
452
|
|
@@ -450,6 +456,7 @@ module Shipit
|
|
450
456
|
|
451
457
|
def active_task
|
452
458
|
return @active_task if defined?(@active_task)
|
459
|
+
|
453
460
|
@active_task ||= tasks.current
|
454
461
|
end
|
455
462
|
|
@@ -496,7 +503,7 @@ module Shipit
|
|
496
503
|
env = stack.cached_deploy_spec.default_deploy_env
|
497
504
|
current_user = Shipit::CommandLineUser.new
|
498
505
|
|
499
|
-
stack.trigger_deploy(until_commit, current_user, env
|
506
|
+
stack.trigger_deploy(until_commit, current_user, env:, force: true, run_now: true)
|
500
507
|
end
|
501
508
|
|
502
509
|
def self.from_param!(param)
|
@@ -505,16 +512,16 @@ module Shipit
|
|
505
512
|
.where(
|
506
513
|
repositories: {
|
507
514
|
owner: repo_owner.downcase,
|
508
|
-
name: repo_name.downcase
|
515
|
+
name: repo_name.downcase
|
509
516
|
},
|
510
|
-
environment:
|
517
|
+
environment:
|
511
518
|
).first!
|
512
519
|
end
|
513
520
|
|
514
521
|
delegate :plugins, :task_definitions, :hidden_statuses, :required_statuses, :soft_failing_statuses,
|
515
|
-
|
516
|
-
|
517
|
-
|
522
|
+
:blocking_statuses, :deploy_variables, :filter_task_envs, :filter_deploy_envs,
|
523
|
+
:maximum_commits_per_deploy, :pause_between_deploys, :retries_on_deploy, :retries_on_rollback,
|
524
|
+
to: :cached_deploy_spec
|
518
525
|
|
519
526
|
def monitoring?
|
520
527
|
monitoring.present?
|
@@ -539,16 +546,16 @@ module Shipit
|
|
539
546
|
end
|
540
547
|
|
541
548
|
def update_latest_deployed_ref
|
542
|
-
|
543
|
-
|
544
|
-
|
549
|
+
return unless Shipit.update_latest_deployed_ref
|
550
|
+
|
551
|
+
UpdateGithubLastDeployedRefJob.perform_later(self)
|
545
552
|
end
|
546
553
|
|
547
554
|
def broadcast_update
|
548
555
|
Pubsubstub.publish(
|
549
556
|
"stack.#{id}",
|
550
|
-
{ id
|
551
|
-
name: 'update'
|
557
|
+
{ id:, updated_at: }.to_json,
|
558
|
+
name: 'update'
|
552
559
|
)
|
553
560
|
end
|
554
561
|
|
@@ -620,14 +627,18 @@ module Shipit
|
|
620
627
|
return unless previous_changes.include?('lock_reason')
|
621
628
|
|
622
629
|
lock_details = if previous_changes['lock_reason'].last.blank?
|
623
|
-
|
624
|
-
|
630
|
+
{ from: previous_changes['locked_since'].first, until: Time.zone.now }
|
631
|
+
end
|
625
632
|
|
626
|
-
Hook.emit(:lock, self, locked: locked?, lock_details
|
633
|
+
Hook.emit(:lock, self, locked: locked?, lock_details:, stack: self)
|
627
634
|
end
|
628
635
|
|
629
636
|
private
|
630
637
|
|
638
|
+
def deployable_commits(commits)
|
639
|
+
commits.to_a.reverse.find(&:deployable?)
|
640
|
+
end
|
641
|
+
|
631
642
|
def clear_cache
|
632
643
|
remove_instance_variable(:@active_task) if defined?(@active_task)
|
633
644
|
end
|
@@ -654,9 +665,9 @@ module Shipit
|
|
654
665
|
end
|
655
666
|
|
656
667
|
def schedule_merges_if_necessary
|
657
|
-
|
658
|
-
|
659
|
-
|
668
|
+
return unless lock_reason_previously_changed? && lock_reason.blank?
|
669
|
+
|
670
|
+
schedule_merges
|
660
671
|
end
|
661
672
|
|
662
673
|
def emit_added_hooks
|
@@ -664,7 +675,7 @@ module Shipit
|
|
664
675
|
end
|
665
676
|
|
666
677
|
def emit_updated_hooks
|
667
|
-
changed = !(previous_changes.keys - %w
|
678
|
+
changed = !(previous_changes.keys - %w[updated_at]).empty?
|
668
679
|
Hook.emit(:stack, self, action: :updated, stack: self) if changed
|
669
680
|
end
|
670
681
|
|
@@ -673,7 +684,7 @@ module Shipit
|
|
673
684
|
end
|
674
685
|
|
675
686
|
def emit_merge_status_hooks
|
676
|
-
Hook.emit(:merge_status, self, merge_status
|
687
|
+
Hook.emit(:merge_status, self, merge_status:, stack: self)
|
677
688
|
end
|
678
689
|
|
679
690
|
def ci_enabled_cache_key
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Shipit
|
3
4
|
class Status
|
4
5
|
class Group
|
@@ -31,7 +32,7 @@ module Shipit
|
|
31
32
|
end
|
32
33
|
|
33
34
|
delegate :pending?, :success?, :error?, :failure?, :unknown?, :missing?, :state, :simple_state,
|
34
|
-
|
35
|
+
to: :significant_status
|
35
36
|
delegate :each, :size, :map, to: :statuses
|
36
37
|
delegate :required_statuses, to: :commit
|
37
38
|
|
@@ -43,8 +44,7 @@ module Shipit
|
|
43
44
|
"#{success_count} / #{statuses.count} checks OK"
|
44
45
|
end
|
45
46
|
|
46
|
-
def target_url
|
47
|
-
end
|
47
|
+
def target_url; end
|
48
48
|
|
49
49
|
def to_partial_path
|
50
50
|
'statuses/group'
|
@@ -75,8 +75,10 @@ module Shipit
|
|
75
75
|
def select_significant_status(statuses)
|
76
76
|
statuses = reject_allowed_to_fail(statuses)
|
77
77
|
return Status::Unknown.new(commit) if statuses.empty?
|
78
|
+
|
78
79
|
non_success_statuses = statuses.reject(&:success?)
|
79
80
|
return statuses.first if non_success_statuses.empty?
|
81
|
+
|
80
82
|
non_success_statuses.reject(&:pending?).first || non_success_statuses.first || Status::Unknown.new(commit)
|
81
83
|
end
|
82
84
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Shipit
|
3
4
|
class Status
|
4
5
|
class Missing
|
@@ -24,7 +25,7 @@ module Shipit
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def description
|
27
|
-
I18n.t('missing_status.description', context:
|
28
|
+
I18n.t('missing_status.description', context:)
|
28
29
|
end
|
29
30
|
|
30
31
|
def to_partial_path
|
data/app/models/shipit/status.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Shipit
|
3
4
|
class Status < Record
|
4
5
|
include Common
|
5
6
|
include DeferredTouch
|
6
7
|
|
7
|
-
STATES = %w
|
8
|
-
enum state
|
8
|
+
STATES = %w[pending success failure error].freeze
|
9
|
+
enum :state, STATES.zip(STATES).to_h
|
9
10
|
|
10
11
|
belongs_to :stack, required: true
|
11
12
|
belongs_to :commit, required: true
|
@@ -22,12 +23,12 @@ module Shipit
|
|
22
23
|
class << self
|
23
24
|
def replicate_from_github!(stack_id, github_status)
|
24
25
|
find_or_create_by!(
|
25
|
-
stack_id
|
26
|
+
stack_id:,
|
26
27
|
state: github_status.state,
|
27
28
|
description: github_status.description,
|
28
29
|
target_url: github_status.target_url,
|
29
30
|
context: github_status.context,
|
30
|
-
created_at: github_status.created_at
|
31
|
+
created_at: github_status.created_at
|
31
32
|
)
|
32
33
|
end
|
33
34
|
end
|
data/app/models/shipit/task.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Shipit
|
3
4
|
class Task < Record
|
4
5
|
include DeferredTouch
|
5
6
|
|
6
|
-
ConcurrentTaskRunning
|
7
|
+
class ConcurrentTaskRunning < StandardError
|
8
|
+
def message
|
9
|
+
"A task is already running."
|
10
|
+
end
|
11
|
+
end
|
7
12
|
|
8
13
|
PRESENCE_CHECK_TIMEOUT = 30
|
9
|
-
ACTIVE_STATUSES = %w
|
10
|
-
COMPLETED_STATUSES = %w
|
11
|
-
UNSUCCESSFUL_STATUSES = %w
|
14
|
+
ACTIVE_STATUSES = %w[pending running aborting].freeze
|
15
|
+
COMPLETED_STATUSES = %w[success flapping faulty validating].freeze
|
16
|
+
UNSUCCESSFUL_STATUSES = %w[error failed aborted flapping timedout faulty].freeze
|
12
17
|
OUTPUT_SIZE_LIMIT = 16.megabytes # A MySQL mediumblob
|
13
18
|
HUMAN_READABLE_OUTPUT_LIMIT = ActionController::Base.helpers.number_to_human_size(OUTPUT_SIZE_LIMIT)
|
14
|
-
OUTPUT_TRUNCATED_MESSAGE = "Output exceeded the limit of #{HUMAN_READABLE_OUTPUT_LIMIT} and was truncated\n"
|
19
|
+
OUTPUT_TRUNCATED_MESSAGE = "Output exceeded the limit of #{HUMAN_READABLE_OUTPUT_LIMIT} and was truncated\n".freeze
|
15
20
|
|
16
21
|
attr_accessor :pid
|
17
22
|
|
@@ -31,6 +36,7 @@ module Shipit
|
|
31
36
|
class << self
|
32
37
|
def dump(hash)
|
33
38
|
raise TypeError, "Task#env should be a Hash[String => String]" unless hash.is_a?(Hash)
|
39
|
+
|
34
40
|
hash = hash.to_h.stringify_keys
|
35
41
|
hash.transform_values! do |value|
|
36
42
|
case value
|
@@ -45,7 +51,7 @@ module Shipit
|
|
45
51
|
end
|
46
52
|
|
47
53
|
def load(hash)
|
48
|
-
hash
|
54
|
+
hash.to_h # cast back to a real hash
|
49
55
|
end
|
50
56
|
|
51
57
|
def new
|
@@ -54,8 +60,8 @@ module Shipit
|
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
57
|
-
serialize :definition, TaskDefinition
|
58
|
-
serialize :env, Shipit.serialized_column(:env, coder: EnvHash)
|
63
|
+
serialize :definition, coder: TaskDefinition
|
64
|
+
serialize :env, coder: Shipit.serialized_column(:env, coder: EnvHash)
|
59
65
|
|
60
66
|
scope :success, -> { where(status: 'success') }
|
61
67
|
scope :completed, -> { where(status: COMPLETED_STATUSES) }
|
@@ -100,11 +106,11 @@ module Shipit
|
|
100
106
|
task.ended_at ||= Time.now.utc
|
101
107
|
end
|
102
108
|
|
103
|
-
after_transition any => %i
|
109
|
+
after_transition any => %i[success failed error timedout] do |task|
|
104
110
|
task.async_refresh_deployed_revision
|
105
111
|
end
|
106
112
|
|
107
|
-
after_transition any => %i
|
113
|
+
after_transition any => %i[aborted success failed error timedout] do |task|
|
108
114
|
task.schedule_rollup_chunks
|
109
115
|
end
|
110
116
|
|
@@ -116,7 +122,7 @@ module Shipit
|
|
116
122
|
task.async_update_estimated_deploy_duration
|
117
123
|
end
|
118
124
|
|
119
|
-
after_transition any => %i
|
125
|
+
after_transition any => %i[failed error timedout] do |task|
|
120
126
|
task.retry_if_necessary
|
121
127
|
end
|
122
128
|
|
@@ -125,19 +131,19 @@ module Shipit
|
|
125
131
|
end
|
126
132
|
|
127
133
|
event :failure do
|
128
|
-
transition %i
|
134
|
+
transition %i[running flapping] => :failed
|
129
135
|
end
|
130
136
|
|
131
137
|
event :complete do
|
132
|
-
transition %i
|
138
|
+
transition %i[running flapping validating faulty] => :success
|
133
139
|
end
|
134
140
|
|
135
141
|
event :enter_validation do
|
136
|
-
transition %i
|
142
|
+
transition %i[running flapping] => :validating
|
137
143
|
end
|
138
144
|
|
139
145
|
event :mark_faulty do
|
140
|
-
transition %i
|
146
|
+
transition %i[validating success] => :faulty
|
141
147
|
end
|
142
148
|
|
143
149
|
event :error do
|
@@ -149,7 +155,7 @@ module Shipit
|
|
149
155
|
end
|
150
156
|
|
151
157
|
event :aborting do
|
152
|
-
transition all - %i
|
158
|
+
transition all - %i[aborted] => :aborting
|
153
159
|
end
|
154
160
|
|
155
161
|
event :aborted do
|
@@ -157,7 +163,7 @@ module Shipit
|
|
157
163
|
end
|
158
164
|
|
159
165
|
event :flap do
|
160
|
-
transition %i
|
166
|
+
transition %i[failed error timedout success] => :flapping
|
161
167
|
end
|
162
168
|
|
163
169
|
state :pending
|
@@ -202,7 +208,7 @@ module Shipit
|
|
202
208
|
end
|
203
209
|
|
204
210
|
delegate :acquire_git_cache_lock, :async_refresh_deployed_revision, :async_update_estimated_deploy_duration,
|
205
|
-
|
211
|
+
to: :stack
|
206
212
|
|
207
213
|
delegate :checklist, to: :definition
|
208
214
|
|
@@ -215,16 +221,18 @@ module Shipit
|
|
215
221
|
end
|
216
222
|
|
217
223
|
def spec
|
218
|
-
@spec ||= DeploySpec::FileSystem.new(working_directory, stack
|
224
|
+
@spec ||= DeploySpec::FileSystem.new(working_directory, stack)
|
219
225
|
end
|
220
226
|
|
221
227
|
def enqueue
|
222
228
|
raise "only persisted jobs can be enqueued" unless persisted?
|
229
|
+
|
223
230
|
PerformTaskJob.perform_later(self)
|
224
231
|
end
|
225
232
|
|
226
233
|
def run_now!
|
227
234
|
raise "only persisted jobs can be run" unless persisted?
|
235
|
+
|
228
236
|
PerformTaskJob.perform_now(self)
|
229
237
|
end
|
230
238
|
|
@@ -346,10 +354,10 @@ module Shipit
|
|
346
354
|
end
|
347
355
|
end
|
348
356
|
|
349
|
-
def abort!(rollback_once_aborted: false, rollback_once_aborted_to: nil
|
357
|
+
def abort!(aborted_by:, rollback_once_aborted: false, rollback_once_aborted_to: nil)
|
350
358
|
update!(
|
351
|
-
rollback_once_aborted
|
352
|
-
rollback_once_aborted_to
|
359
|
+
rollback_once_aborted:,
|
360
|
+
rollback_once_aborted_to:,
|
353
361
|
aborted_by_id: aborted_by.id
|
354
362
|
)
|
355
363
|
|
@@ -379,12 +387,13 @@ module Shipit
|
|
379
387
|
|
380
388
|
def emit_hooks_if_status_changed
|
381
389
|
return unless @status_changed
|
390
|
+
|
382
391
|
@status_changed = nil
|
383
392
|
emit_hooks
|
384
393
|
end
|
385
394
|
|
386
395
|
def emit_hooks
|
387
|
-
Hook.emit(hook_event, stack, hook_event => self, status
|
396
|
+
Hook.emit(hook_event, stack, hook_event => self, status:, stack:)
|
388
397
|
end
|
389
398
|
|
390
399
|
def hook_event
|
@@ -423,13 +432,13 @@ module Shipit
|
|
423
432
|
5.minutes.ago
|
424
433
|
end
|
425
434
|
|
426
|
-
ZOMBIE_STATES = %w
|
435
|
+
ZOMBIE_STATES = %w[running aborting].freeze
|
427
436
|
private_constant :ZOMBIE_STATES
|
428
437
|
def self.zombies
|
429
438
|
where(status: ZOMBIE_STATES)
|
430
439
|
.where(
|
431
440
|
"created_at <= :recently",
|
432
|
-
recently: recently_created_at
|
441
|
+
recently: recently_created_at
|
433
442
|
)
|
434
443
|
.reject(&:alive?)
|
435
444
|
end
|
@@ -437,13 +446,13 @@ module Shipit
|
|
437
446
|
def retry_if_necessary
|
438
447
|
return unless retries_configured? && !stack.reload.locked?
|
439
448
|
|
440
|
-
|
441
|
-
retry_task = duplicate_task
|
442
|
-
retry_task.retry_attempt = duplicate_task.retry_attempt + 1
|
443
|
-
retry_task.save!
|
449
|
+
return unless retry_attempt < max_retries
|
444
450
|
|
445
|
-
|
446
|
-
|
451
|
+
retry_task = duplicate_task
|
452
|
+
retry_task.retry_attempt = duplicate_task.retry_attempt + 1
|
453
|
+
retry_task.save!
|
454
|
+
|
455
|
+
retry_task.enqueue
|
447
456
|
end
|
448
457
|
|
449
458
|
def retries_configured?
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Shipit
|
3
4
|
class TaskDefinition
|
4
5
|
NotFound = Class.new(StandardError)
|
@@ -6,18 +7,20 @@ module Shipit
|
|
6
7
|
class << self
|
7
8
|
def load(payload)
|
8
9
|
return if payload.blank?
|
10
|
+
|
9
11
|
json = JSON.parse(payload)
|
10
12
|
new(json.delete('id'), json)
|
11
13
|
end
|
12
14
|
|
13
15
|
def dump(definition)
|
14
16
|
return if definition.blank?
|
17
|
+
|
15
18
|
JSON.dump(definition.as_json)
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
19
22
|
attr_reader :id, :action, :description, :steps, :checklist, :variables
|
20
|
-
|
23
|
+
alias to_param id
|
21
24
|
|
22
25
|
def initialize(id, config)
|
23
26
|
@id = id
|
@@ -46,14 +49,14 @@ module Shipit
|
|
46
49
|
|
47
50
|
def as_json
|
48
51
|
{
|
49
|
-
id
|
50
|
-
action
|
52
|
+
id:,
|
53
|
+
action:,
|
51
54
|
title: @title,
|
52
|
-
description
|
53
|
-
steps
|
55
|
+
description:,
|
56
|
+
steps:,
|
54
57
|
variables: variables.map(&:to_h),
|
55
|
-
checklist
|
56
|
-
allow_concurrency: allow_concurrency
|
58
|
+
checklist:,
|
59
|
+
allow_concurrency: allow_concurrency?
|
57
60
|
}
|
58
61
|
end
|
59
62
|
|