Skip to content

Commit 339f6ab

Browse files
authored
Add new release workflows (#290)
This will also require updates to minty's config.
1 parent bba64a1 commit 339f6ab

File tree

6 files changed

+395
-270
lines changed

6 files changed

+395
-270
lines changed
+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# Copyright 2024 The Authors (see AUTHORS file)
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
#
16+
# This GitHub Action creates a Git tag and associated GitHub Release at the current SHA.
17+
#
18+
# It includes two outputs: the "current_version" and the "next_version".
19+
#
20+
# Example usage:
21+
#
22+
# jobs:
23+
# release:
24+
# runs-on: 'ubuntu-latest'
25+
#
26+
# # The following line is super super super important! This ensures the
27+
# # job only runs when the commit matches the expected message. There
28+
# # are additional checks in the action itself, including commit
29+
# # signature verification, but adding this line prevents the workflow
30+
# # from running at all, saving your previous GitHub Actions usage
31+
# #minutes.
32+
# if: '${{ startsWith(github.event.head_commit.message, ''Release: v'')
33+
#
34+
# steps:
35+
# - name: 'Create release'
36+
# id: 'create-release'
37+
# uses: 'abcxyz/pkg/.github/actions/create-release@main'
38+
# with:
39+
# github_token: '${{ secrets.GITHUB_TOKEN }}' # Or an organization PAT
40+
# expected_email: '[email protected]'
41+
#
42+
# # Example using go-releaser
43+
# - uses: 'actions/checkout@v4'
44+
# with:
45+
# fetch-depth: 0
46+
#
47+
# - uses: 'actions/setup-go@v5'
48+
# with:
49+
# go-version: '1.21'
50+
#
51+
# - uses: 'goreleaser/goreleaser-action@v5'
52+
# with:
53+
# args: 'release --clean'
54+
# env:
55+
# GORELEASER_CURRENT_TAG: 'v${{ steps.create-release.outputs.release_version }}'
56+
# GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' # Or an organization PAT
57+
#
58+
59+
name: 'create-release'
60+
61+
inputs:
62+
github_token:
63+
description: |-
64+
GitHub PAT or App Token to use for authentication.
65+
type: 'string'
66+
required: true
67+
68+
expected_email:
69+
description: |-
70+
Email address expected for the commit.
71+
type: 'string'
72+
required: true
73+
74+
draft:
75+
description: |-
76+
Create the release as a draft.
77+
type: 'boolean'
78+
required: false
79+
default: false
80+
81+
outputs:
82+
release_version:
83+
description: |-
84+
Version that is being released, without a leading "v".
85+
value: '${{ steps.create-release.outputs.release_version }}'
86+
87+
runs:
88+
using: 'composite'
89+
steps:
90+
- name: 'Create release'
91+
id: 'create-release'
92+
env:
93+
DRAFT: '${{ inputs.draft }}'
94+
EXPECTED_EMAIL: '${{ inputs.expected_email }}'
95+
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7
96+
with:
97+
github-token: '${{ inputs.github_token }}'
98+
script: |-
99+
// Ensure the commit is signed.
100+
const commitResult = await github.rest.repos.getCommit({
101+
owner: context.repo.owner,
102+
repo: context.repo.repo,
103+
ref: context.payload.head_commit.id,
104+
})
105+
if (!commitResult.data.commit.verification.verified) {
106+
core.setFailed(`Commit is not signed`)
107+
return;
108+
}
109+
110+
const expectedEmail = process.env.EXPECTED_EMAIL;
111+
if (commitResult.data.commit.author.email !== expectedEmail) {
112+
core.setFailed(`Commit author is not ${expectedEmail}, got ${commitResult.data.commit.author.email}`);
113+
return;
114+
}
115+
if (commitResult.data.commit.committer.email !== expectedEmail) {
116+
core.setFailed(`Commiter is not ${expectedEmail}, got ${commitResult.data.commit.committer.email}`);
117+
return;
118+
}
119+
120+
// Ensure the commit message matches the expected regular
121+
// expression. Part of this is guarded by the conditional
122+
// entrypoint.
123+
const matches = context.payload.head_commit.message.match(/Release: v(?<version>[^\ ]+)/i);
124+
if (!matches || !matches.groups) {
125+
core.setFailed(`Commit message does not contain a version`)
126+
return;
127+
}
128+
let releaseVersion = matches.groups.version;
129+
while(releaseVersion.charAt(0).toLowerCase() === 'v') {
130+
releaseVersion = releaseVersion.substr(1);
131+
}
132+
133+
// Compute variables.
134+
const tag = `v${releaseVersion}`;
135+
const draft = JSON.parse(process.env.DRAFT);
136+
const prerelease = ['-', 'pre', 'alpha', 'beta', 'preview'].some((v) => tag.includes(v));
137+
138+
try {
139+
const createReleaseRequest = {
140+
owner: context.repo.owner,
141+
repo: context.repo.repo,
142+
tag_name: tag,
143+
target_commitish: context.sha,
144+
name: tag,
145+
generate_release_notes: true,
146+
prerelease: prerelease,
147+
draft: draft,
148+
};
149+
150+
const response = await github.rest.repos.createRelease(createReleaseRequest);
151+
152+
core.setOutput('release_version', releaseVersion);
153+
core.info(
154+
`Created release ${response.data.name} at ${response.data.html_url}`
155+
);
156+
} catch (err) {
157+
core.setFailed(`Failed to create release: ${err}`);
158+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Copyright 2024 The Authors (see AUTHORS file)
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
#
16+
# This GitHub Action increments a VERSION file at the root of the repository by
17+
# the given semver strategy. If no VERSION file exists, it uses "0.0.0". It does
18+
# not commit the resulting file.
19+
#
20+
# It includes two outputs: the "current_version" and the "next_version".
21+
#
22+
# Example usage:
23+
#
24+
# jobs:
25+
# draft-release:
26+
# runs-on: 'ubuntu-latest'
27+
# steps:
28+
# - name: 'Increment version'
29+
# id: 'increment-version'
30+
# uses: 'abcxyz/pkg/.github/actions/increment-version@main'
31+
# with:
32+
# version_strategy: 'patch' # Likely from "workflow_call" input
33+
#
34+
# - name: 'Update npm version'
35+
# env:
36+
# NEXT_VERSION: '${{ steps.increment-version.outputs.next_version }}'
37+
# run: |-
38+
# npm version ${NEXT_VERSION} --no-git-tag-version
39+
#
40+
41+
name: 'increment-version'
42+
43+
inputs:
44+
version_strategy:
45+
description: |-
46+
Strategy to update the version based on semantic versioning.
47+
default: 'patch'
48+
type: 'string'
49+
required: true
50+
51+
prerelease_identifier:
52+
description: |-
53+
String to use to identify pre-releases.
54+
type: 'string'
55+
default: 'alpha'
56+
required: false
57+
58+
outputs:
59+
current_version:
60+
description: |-
61+
Existing version prior to incrementing, without any leading "v" prefixes.
62+
value: '${{ steps.increment-version.outputs.current_version }}'
63+
64+
next_version:
65+
description: |-
66+
Incremented version, without any leading "v" prefixes.
67+
value: '${{ steps.increment-version.outputs.next_version }}'
68+
69+
runs:
70+
using: 'composite'
71+
steps:
72+
- uses: 'actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11' # ratchet:actions/checkout@v4
73+
74+
- name: 'Increment version'
75+
id: 'increment-version'
76+
env:
77+
PRERELEASE_IDENTIFIER: '${{ inputs.prerelease_identifier }}'
78+
VERSION_STRATEGY: '${{ inputs.version_strategy }}'
79+
shell: 'bash'
80+
run: |-
81+
npm install -g --silent --quiet --no-progress [email protected]
82+
83+
CURRENT_VERSION="0.0.0"
84+
if [ -f "${GITHUB_WORKSPACE}/VERSION" ]; then
85+
CURRENT_VERSION="$(< "${GITHUB_WORKSPACE}/VERSION")"
86+
fi
87+
echo "CURRENT_VERSION: ${CURRENT_VERSION}"
88+
echo "current_version=${CURRENT_VERSION}" >> "${GITHUB_OUTPUT}"
89+
echo "CURRENT_VERSION=${CURRENT_VERSION}" >> "${GITHUB_ENV}"
90+
91+
NEXT_VERSION="$(semver "${CURRENT_VERSION}" \
92+
--increment "${VERSION_STRATEGY}" \
93+
--preid "${PRERELEASE_IDENTIFIER}" \
94+
-n 1)"
95+
echo "NEXT_VERSION: ${NEXT_VERSION}"
96+
97+
echo "next_version=${NEXT_VERSION}" >> "${GITHUB_OUTPUT}"
98+
echo "NEXT_VERSION=${NEXT_VERSION}" >> "${GITHUB_ENV}"
99+
echo "${NEXT_VERSION}" > "${GITHUB_WORKSPACE}/VERSION"

0 commit comments

Comments
 (0)