diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f1b907a..6db4f97 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,14 @@ stages: - components - !reference [.release-coordinator:canary:stages] +workflow: + name: $PIPELINE_NAME + rules: + - if: $CI_PIPELINE_SOURCE == "push" + variables: + PIPELINE_NAME: "Build pyxis image for $CI_COMMIT_SHORT_SHA" + - if: $PIPELINE_NAME != null + default: image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA tags: diff --git a/.gitlab/ci/release-coordinator.canary.gitlab-ci.yml b/.gitlab/ci/release-coordinator.canary.gitlab-ci.yml index 72a3a20..05db2b1 100644 --- a/.gitlab/ci/release-coordinator.canary.gitlab-ci.yml +++ b/.gitlab/ci/release-coordinator.canary.gitlab-ci.yml @@ -1,11 +1,22 @@ .release-coordinator:canary:stages: + - release-coordinator:canary:notify-start - release-coordinator:canary:build - release-coordinator:canary:publish + - release-coordinator:canary:notify-finish .release-coordinator:canary: rules: - if: $RELEASE_COORDINATOR == "canary" +release-coordinator:canary:notify-start: + extends: + - .release-coordinator:canary + stage: release-coordinator:canary:notify-start + script: + - bin/pyxis internal notify_new_coordinator --coordinator-pipeline-id $CI_PIPELINE_ID + variables: + DRY_RUN: "false" + release-coordinator:canary:tmp-branch: extends: - .release-coordinator:canary @@ -55,6 +66,14 @@ release-coordinator:canary:publish: - echo "Publishing approved" when: manual +release-coordinator:canary:notify-publish-pending: + extends: + - .release-coordinator:canary + stage: release-coordinator:canary:publish + needs: !reference [release-coordinator:canary:publish, needs] + script: + - bin/pyxis internal release_notify_publish_pending + release-coordinator:canary:publish-containers: extends: - .release-coordinator:canary @@ -76,3 +95,12 @@ release-coordinator:canary:publish-release: - bin/pyxis internal release_canary_publish_release --coordinator-pipeline-id $CI_PIPELINE_ID variables: DRY_RUN: "false" + +release-coordinator:canary:notify-finish: + extends: + - .release-coordinator:canary + stage: release-coordinator:canary:notify-finish + script: + - bin/pyxis internal notify_finish_coordinator --coordinator-pipeline-id $CI_PIPELINE_ID + variables: + DRY_RUN: "false" diff --git a/lib/pyxis/commands/internal.rb b/lib/pyxis/commands/internal.rb index c98b94d..52424cb 100644 --- a/lib/pyxis/commands/internal.rb +++ b/lib/pyxis/commands/internal.rb @@ -28,6 +28,54 @@ def release_canary_publish_tags def release_canary_publish_release Pyxis::Release::Canary.new.publish_release(options[:coordinator_pipeline_id]) end + + desc 'release_notify_publish_pending', '' + method_option :coordinator_pipeline_id, required: true, type: :numeric + def release_notify_publish_pending + pipeline = GitlabClient.client.get_pipeline( + Project::Pyxis.api_gitlab_path, + options[:coordinator_pipeline_id] + ).body + raise 'Pipeline not found' if pipeline.nil? + + Pyxis::DiscordClient.new.send_notification(<<~DESC, :warn) + Coordinator pipeline awaiting approval for release publishing + #{"> #{pipeline.name}" if pipeline.name} + #{pipeline.web_url} + DESC + end + + desc 'notify_new_coordinator', '' + method_option :coordinator_pipeline_id, required: true, type: :numeric + def notify_new_coordinator + pipeline = GitlabClient.client.get_pipeline( + Project::Pyxis.api_gitlab_path, + options[:coordinator_pipeline_id] + ).body + raise 'Pipeline not found' if pipeline.nil? + + Pyxis::DiscordClient.new.send_notification(<<~DESC) + New coordinator pipeline started + #{"> #{pipeline.name}" if pipeline.name} + #{pipeline.web_url} + DESC + end + + desc 'notify_finish_coordinator', '' + method_option :coordinator_pipeline_id, required: true, type: :numeric + def notify_finish_coordinator + pipeline = GitlabClient.client.get_pipeline( + Project::Pyxis.api_gitlab_path, + options[:coordinator_pipeline_id] + ).body + raise 'Pipeline not found' if pipeline.nil? + + Pyxis::DiscordClient.new.send_notification(<<~DESC) + Coordinator pipeline has finished + #{"> #{pipeline.name}" if pipeline.name} + #{pipeline.web_url} + DESC + end end end end diff --git a/lib/pyxis/commands/release.rb b/lib/pyxis/commands/release.rb index 9f118a0..712a4cf 100644 --- a/lib/pyxis/commands/release.rb +++ b/lib/pyxis/commands/release.rb @@ -33,6 +33,7 @@ def create_canary Project::Pyxis.api_gitlab_path, Project::Pyxis.default_branch, variables: { + PIPELINE_NAME: "Release build #{build_id} as canary", RELEASE_COORDINATOR: 'canary', BUILD_ID_TO_PROMOTE: build_id.to_s, } diff --git a/lib/pyxis/discord_client.rb b/lib/pyxis/discord_client.rb new file mode 100644 index 0000000..319a19e --- /dev/null +++ b/lib/pyxis/discord_client.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Pyxis + class DiscordClient + LOG_CHANNEL = 1478849342101000222 + + COLOR_MAPPING = { + info: '#4caf50', + warn: '#ff8000', + error: '#f44336', + }.freeze + + attr_reader :bot + + def initialize + @bot = Discordrb::Bot.new(token: Pyxis::Environment.discord_bot_token) + end + + def send_notification(message, severity = :info) + embed = Discordrb::Webhooks::Embed.new(description: message, color: COLOR_MAPPING[severity]) + + bot.send_message(LOG_CHANNEL, nil, false, [embed]) + end + end +end diff --git a/lib/pyxis/gitlab_client.rb b/lib/pyxis/gitlab_client.rb index 2c99bc3..1cc39da 100644 --- a/lib/pyxis/gitlab_client.rb +++ b/lib/pyxis/gitlab_client.rb @@ -95,6 +95,10 @@ def create_pipeline(project_path_or_id, ref, variables: nil) ) end + def get_pipeline(project_path_or_id, id) + get_json("/api/v4/projects/#{project_path_or_id}/pipelines/#{id}") + end + def list_pipeline_bridges(project_path_or_id, pipeline_id) paginate_json("/api/v4/projects/#{project_path_or_id}/pipelines/#{pipeline_id}/bridges") end diff --git a/lib/pyxis/managed_versioning/component_info.rb b/lib/pyxis/managed_versioning/component_info.rb index fac3900..ade9f8e 100644 --- a/lib/pyxis/managed_versioning/component_info.rb +++ b/lib/pyxis/managed_versioning/component_info.rb @@ -141,9 +141,7 @@ def find_container_version(jobs) end def load_pipeline(pipeline_id) - pipeline = GitlabClient.client.get_json( - "/api/v4/projects/#{Project::Reticulum.api_gitlab_path}/pipelines/#{pipeline_id}" - ) + pipeline = GitlabClient.client.get_pipeline(Project::Reticulum.api_gitlab_path, pipeline_id) return nil if pipeline.response.status == 404 [