👉 Subscribe to our newsletter to get:
- Real stories from real AWS projects
- No-nonsense DevOps tactics
- Cost, security & compliance patterns that actually work
- Expert guidance from engineers in the field
=========================================================================
Deployment confirmation button for Slack
Configuration is done via env variables
SLACK_BOT_TOKEN- Slack bot token. Mandatory parameter. scopes: channels:history, chat:write, reactions:read, users:read.email, users:readSLACK_APP_TOKEN- Slack app token. Mandatory parameter. scopes: connections:writeSLACK_CHANNEL_NAME- Slack channel name. Also channel_id can be usedTRIGGERED_BY_EMAIL- Email of the person who triggered the build, for example by pressing the merge button. Optional parameter. When set, aTriggered byline is added to the approval message, mentioning that person if the email matches a Slack profile. Useful because the commit itself does not always point at a person: squash merges on GitHub, for instance, are committed asnoreply@github.com. A GitHub-generated noreply address (barenoreply@github.comor the privacy-enabled<id>+<username>@users.noreply.github.comform) never resolves to a person, so theTriggered byline is omitted entirely rather than showing that address
_metadata:
major_version: 1
minor_version: 1
display_information:
name: MagicButton
description: Deployment confirmation
background_color: "#2645a3"
features:
bot_user:
display_name: MagicButton
always_online: false
oauth_config:
scopes:
bot:
- channels:history
- chat:write
- reactions:read
- users:read.email
- users:read
settings:
interactivity:
is_enabled: true
org_deploy_enabled: false
socket_mode_enabled: true
token_rotation_enabled: false{
"timestamp": 1669891821,
"approval_code": 0,
"usernames": [
"vladimir.samoylov"
],
"teams": [
"fivexl"
],
"channel": "magic-button",
"message": "Approval request for job local-test"
} # Repo metadata - output of this step will be used by the later steps. Search for steps.repo.outputs to see where
- name: Repo metadata
id: repo
uses: actions/github-script@v3
with:
script: |
const repo = await github.repos.get(context.repo)
return repo.data
- name: Approval
id: approval
if: steps.checkout.outcome == 'success'
env:
MAGIC_BUTTON_VERSION: "v0.2.0"
SLACK_BOT_TOKEN: "${{ secrets.SLACK_BOT_TOKEN }}"
SLACK_APP_TOKEN: "${{ secrets.SLACK_APP_TOKEN }}"
SLACK_CHANNEL_NAME: "${{ secrets.SLACK_CHANNEL_NAME }}"
BUILD_JOB_NAME: "${{ github.event.repository.name }}"
BUILD_JOB_URL: "${{ fromJson(steps.repo.outputs.result).html_url }}/actions"
PRODUCTION_BRANCHES: release
BRANCHES_TO_PROMOTE: "${{ env.GIT_DESTINATION_BRANCH }}"
TIMEOUT_MINUTES: 1
REPOSITORY_URL: "${{ fromJson(steps.repo.outputs.result).html_url }}"
# Who clicked Merge - not always the commit author/committer (e.g. squash
# merges are committed by GitHub as noreply@github.com). Optional.
TRIGGERED_BY_EMAIL: "${{ github.event.pusher.email }}"
run: >
mkdir -p magic-button/reports && chmod 777 magic-button/reports
&& docker run --rm
-v "$(pwd)/.git":/app/.git
-v "$(pwd)/magic-button/reports":/app/reports
-e SLACK_BOT_TOKEN -e SLACK_APP_TOKEN -e BUILD_JOB_NAME -e BUILD_JOB_URL
-e CURRENT_GIT_COMMIT="$(git rev-parse HEAD)" -e REPOSITORY_NAME="$(basename $(git rev-parse --show-toplevel))"
-e REPOSITORY_URL -e BRANCHES_TO_PROMOTE -e TIMEOUT_MINUTES -e TIMEZONE="Europe/Oslo"
-e PRODUCTION_BRANCHES -e SLACK_CHANNEL_NAME -e TRIGGERED_BY_EMAIL
ghcr.io/fivexl/magic-button:${{ env.MAGIC_BUTTON_VERSION }}
&& ls -all magic-button/reports && cat magic-button/reports/report.json
continue-on-error: true
.magicbutton:
stage: .post
image:
name: docker:latest
services:
- docker:dind
allow_failure: true
before_script:
- apk update
- apk add git
script:
- |
mkdir -p magic-button/reports && chmod 777 magic-button/reports && docker run --rm -v "$(pwd)/.git":/app/.git -v "$(pwd)/magic-button/reports":/app/reports -e SLACK_BOT_TOKEN -e SLACK_APP_TOKEN -e BUILD_JOB_NAME -e BUILD_JOB_URL -e CURRENT_GIT_COMMIT="$(git rev-parse HEAD)" -e REPOSITORY_NAME="$(basename $(git rev-parse --show-toplevel))" -e REPOSITORY_URL -e BRANCHES_TO_PROMOTE -e TIMEOUT_MINUTES -e TIMEZONE="Europe/Oslo" -e PRODUCTION_BRANCHES -e SLACK_CHANNEL_NAME -e TRIGGERED_BY_EMAIL="$GITLAB_USER_EMAIL" ghcr.io/fivexl/magic-button:$MAGIC_BUTTON_VERSION && ls -all magic-button/reports && cat magic-button/reports/report.json
after_script:
- >
if [ $CI_JOB_STATUS == 'success' ]; then
#Provide git credentials (e.g.: https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html)
git remote set-url --push origin git@gitlab:$CI_PROJECT_PATH
git switch $BRANCHES_TO_PROMOTE
git push -f origin HEAD:$PRODUCTION_BRANCHES
else
echo 'Confirmation failed or is cancelled'
fi
promote:
stage: .post
extends: .magicbutton
rules:
- if: $CI_COMMIT_REF_NAME == $BRANCHES_TO_PROMOTE
