Skip to content

Commit 0547f04

Browse files
authored
ci: Add release automation (#170)
* Set up release automation * Add changelog
1 parent 025b660 commit 0547f04

File tree

7 files changed

+205
-0
lines changed

7 files changed

+205
-0
lines changed

.github/workflows/build-lint-test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ jobs:
1616
is-high-risk-environment: false
1717

1818
- run: yarn lint
19+
- name: Validate RC changelog
20+
if: ${{ startsWith(github.head_ref, 'release/') }}
21+
run: yarn lint:changelog --rc
22+
- name: Validate changelog
23+
if: ${{ !startsWith(github.head_ref, 'release/') }}
24+
run: yarn lint:changelog
1925

2026
- name: Require clean working directory
2127
shell: bash
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Create Release Pull Request
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
base-branch:
7+
description: 'The base branch for git operations and the pull request.'
8+
default: 'main'
9+
required: true
10+
release-type:
11+
description: 'A SemVer version diff, i.e. major, minor, or patch. Mutually exclusive with "release-version".'
12+
required: false
13+
release-version:
14+
description: 'A specific version to bump to. Mutually exclusive with "release-type".'
15+
required: false
16+
17+
jobs:
18+
create-release-pr:
19+
runs-on: ubuntu-latest
20+
permissions:
21+
contents: write
22+
pull-requests: write
23+
steps:
24+
- name: Checkout and setup environment
25+
uses: MetaMask/action-checkout-and-setup@v2
26+
with:
27+
is-high-risk-environment: true
28+
29+
# This is to guarantee that the most recent tag is fetched. This can
30+
# be configured to a more reasonable value by consumers.
31+
fetch-depth: 0
32+
33+
# We check out the specified branch, which will be used as the base
34+
# branch for all git operations and the release PR.
35+
ref: ${{ github.event.inputs.base-branch }}
36+
37+
- uses: MetaMask/action-create-release-pr@v4
38+
with:
39+
release-type: ${{ github.event.inputs.release-type }}
40+
release-version: ${{ github.event.inputs.release-version }}
41+
env:
42+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/main.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,28 @@ jobs:
5353
if [[ "$PASSED" != "true" ]]; then
5454
exit 1
5555
fi
56+
57+
is-release:
58+
# Filtering by `push` events ensures that we only release from the `main` branch, which is a
59+
# requirement for our npm publishing environment.
60+
# The commit author should always be 'github-actions' for releases created by the
61+
# 'create-release-pr' workflow, so we filter by that as well to prevent accidentally
62+
# triggering a release.
63+
if: github.event_name == 'push' && startsWith(github.event.head_commit.author.name, 'github-actions')
64+
needs: all-jobs-pass
65+
outputs:
66+
IS_RELEASE: ${{ steps.is-release.outputs.IS_RELEASE }}
67+
runs-on: ubuntu-latest
68+
steps:
69+
- uses: MetaMask/action-is-release@v1
70+
id: is-release
71+
72+
publish-release:
73+
needs: is-release
74+
if: needs.is-release.outputs.IS_RELEASE == 'true'
75+
name: Publish release
76+
permissions:
77+
contents: write
78+
uses: ./.github/workflows/publish-release.yml
79+
secrets:
80+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Publish Release
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
slack-icon-url:
7+
required: false
8+
type: string
9+
default: 'https://raw.githubusercontent.com/MetaMask/action-npm-publish/main/robo.png'
10+
slack-subteam:
11+
required: false
12+
type: string
13+
default: S042S7RE4AE # @metamask-npm-publishers
14+
slack-username:
15+
required: false
16+
type: string
17+
default: 'MetaMask bot'
18+
secrets:
19+
SLACK_WEBHOOK_URL:
20+
required: true
21+
22+
jobs:
23+
announce-release:
24+
name: Announce release
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v5
28+
- id: name-hash
29+
name: Get Slack name and hash
30+
shell: bash
31+
if: inputs.slack-subteam != ''
32+
run: |
33+
NAME_VERSION_TEXT=$(jq --raw-output '.name + "@" + .version' package.json )
34+
NAME_VERSION_TEXT_STRIPPED="${NAME_VERSION_TEXT#@}"
35+
echo "NAME_VERSION=$NAME_VERSION_TEXT_STRIPPED" >> "$GITHUB_OUTPUT"
36+
- id: final-text
37+
name: Get Slack final text
38+
shell: bash
39+
if: inputs.slack-subteam != ''
40+
run: |
41+
DEFAULT_TEXT="\`${{ steps.name-hash.outputs.NAME_VERSION }}\` is awaiting deployment :rocket: \n <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/|→ Click here to review deployment>"
42+
SUBTEAM_TEXT="${{ inputs.slack-subteam }}"
43+
FINAL_TEXT="$DEFAULT_TEXT"
44+
if [[ ! "$SUBTEAM_TEXT" == "" ]]; then
45+
FINAL_TEXT="<!subteam^$SUBTEAM_TEXT> $DEFAULT_TEXT"
46+
fi
47+
echo "FINAL_TEXT=$FINAL_TEXT" >> "$GITHUB_OUTPUT"
48+
- name: Post to a Slack channel
49+
if: inputs.slack-subteam != ''
50+
uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844
51+
with:
52+
payload: |
53+
{
54+
"text": "${{ steps.final-text.outputs.FINAL_TEXT }}",
55+
"icon_url": "${{ inputs.slack-icon-url }}",
56+
"username": "${{ inputs.slack-username }}"
57+
}
58+
env:
59+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
60+
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
61+
continue-on-error: true
62+
63+
publish-release:
64+
name: Publish release
65+
environment: npm-publish
66+
needs: announce-release
67+
permissions:
68+
contents: write
69+
runs-on: ubuntu-latest
70+
steps:
71+
- name: Checkout repository
72+
uses: actions/checkout@v5
73+
with:
74+
# This is to guarantee that the most recent tag is fetched, which we
75+
# need for updating the shorthand major version tag.
76+
fetch-depth: 0
77+
ref: ${{ github.sha }}
78+
- name: Publish release
79+
uses: MetaMask/action-publish-release@v3
80+
id: publish-release
81+
env:
82+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83+
- name: Update shorthand major version tag
84+
run: |
85+
./.github/workflows/scripts/update-major-version-tag.sh \
86+
${{ steps.publish-release.outputs.release-version }}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bash
2+
3+
set -x
4+
set -e
5+
set -o pipefail
6+
7+
RELEASE_VERSION="${1}"
8+
9+
if [[ -z $RELEASE_VERSION ]]; then
10+
echo "Error: No release version specified."
11+
exit 1
12+
fi
13+
14+
MAJOR_VERSION_TAG="v${RELEASE_VERSION/\.*/}"
15+
16+
git config user.name github-actions
17+
git config user.email [email protected]
18+
19+
if git show-ref --tags "$MAJOR_VERSION_TAG" --quiet; then
20+
echo "Tag \"${MAJOR_VERSION_TAG}\" exists, attempting to delete it."
21+
git tag --delete "$MAJOR_VERSION_TAG"
22+
git push --delete origin "$MAJOR_VERSION_TAG"
23+
else
24+
echo "Tag \"${MAJOR_VERSION_TAG}\" does not exist, creating it from scratch."
25+
fi
26+
27+
git tag "$MAJOR_VERSION_TAG" HEAD
28+
git push --tags
29+
echo "Updated shorthand major version tag."
30+
31+
echo "MAJOR_VERSION_TAG=$MAJOR_VERSION_TAG" >> "$GITHUB_OUTPUT"

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
[Unreleased]: https://github.com/MetaMask/github-tools/

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
"version": "0.0.0",
44
"private": true,
55
"description": "Tools for interacting with the GitHub API to do metrics gathering",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/MetaMask/github-tools.git"
9+
},
610
"scripts": {
711
"changelog:check": "ts-node src/changelog-check.ts",
812
"count-references-to-contributor-docs": "ts-node --swc src/scripts/count-references-to-contributor-docs/cli.ts",
913
"gen:commits": "node .github/scripts/generate-rc-commits.mjs",
1014
"get-review-metrics": "ts-node src/get-review-metrics.ts",
1115
"lint": "yarn lint:tsc && yarn lint:eslint && yarn lint:constraints && yarn lint:misc --check && yarn lint:dependencies --check",
1216
"lint:constraints": "yarn constraints",
17+
"lint:changelog": "auto-changelog validate --prettier",
1318
"lint:dependencies": "depcheck && yarn dedupe",
1419
"lint:eslint": "eslint . --cache --ext js,ts",
1520
"lint:fix": "yarn lint:eslint --fix && yarn lint:constraints --fix && yarn lint:misc --write && yarn lint:dependencies",

0 commit comments

Comments
 (0)