Skip to content

Commit 3f22abc

Browse files
chore(CI/CD): add semantic release automation (#949)
Co-authored-by: Lucas McDonald <[email protected]>
1 parent f5d9748 commit 3f22abc

File tree

4 files changed

+299
-0
lines changed

4 files changed

+299
-0
lines changed

.github/workflows/sem_ver.yml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# This workflow tests the installation of semantic release
2+
name: Semantic Release Test Installation
3+
4+
on:
5+
pull_request:
6+
7+
jobs:
8+
semantic-release:
9+
runs-on: macos-latest
10+
permissions:
11+
id-token: write
12+
contents: read
13+
steps:
14+
- name: Support longpaths on Git checkout
15+
run: |
16+
git config --global core.longpaths true
17+
- uses: actions/checkout@v4
18+
with:
19+
submodules: recursive
20+
21+
# We need access to the role that is able to get CI Bot Creds
22+
- name: Configure AWS Credentials for Release
23+
uses: aws-actions/configure-aws-credentials@v2
24+
with:
25+
aws-region: us-west-2
26+
role-to-assume: arn:aws:iam::587316601012:role/GitHub-CI-CI-Bot-Credential-Access-Role-us-west-2
27+
role-session-name: CI_Bot_Release
28+
29+
- name: Upgrade Node
30+
uses: actions/setup-node@v4
31+
with:
32+
node-version: 21
33+
34+
# Use AWS Secrets Manger GHA to retrieve CI Bot Creds
35+
- name: Get CI Bot Creds Secret
36+
uses: aws-actions/aws-secretsmanager-get-secrets@v2
37+
with:
38+
secret-ids: Github/aws-crypto-tools-ci-bot
39+
parse-json-secrets: true
40+
41+
# Log in as the CI Bot
42+
- name: Log in as CI Bot
43+
run: |
44+
echo ${{env.GITHUB_AWS_CRYPTO_TOOLS_CI_BOT_ESDK_RELEASE_TOKEN}} > token.txt
45+
gh auth login --with-token < token.txt
46+
rm token.txt
47+
gh auth status
48+
49+
# Test to see if we can setup semantic release
50+
- name: Test Semantic Release Installation
51+
uses: actions/checkout@v4
52+
- run: |
53+
make setup_semantic_release
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# This workflow runs semantic release, bumps, generates changelog, and tags the project
2+
name: Semantic Release
3+
4+
on:
5+
workflow_dispatch:
6+
inputs:
7+
dry-run:
8+
description: "Is this a dry run to validate semantic-release behaves as expected? (y/n)"
9+
required: true
10+
type: string
11+
12+
jobs:
13+
semantic-release:
14+
# there is no easy way in gha to check if the actor is part of the team, running semantic release is a more
15+
# privileged operation, so we must make sure this list of users is a subset of the users labeled as maintainers of
16+
# https://github.com/orgs/aws/teams/aws-crypto-tools
17+
if: contains('["seebees","texastony","ShubhamChaturvedi7","lucasmcdonald3","josecorella","imabhichow","rishav-karanjit","antonf-amzn","justplaz","ajewellamz","RitvikKapila"]', github.actor)
18+
runs-on: macos-latest
19+
permissions:
20+
id-token: write
21+
contents: write
22+
steps:
23+
- name: Support longpaths on Git checkout
24+
run: |
25+
git config --global core.longpaths true
26+
- uses: actions/checkout@v3
27+
# We only pull in the submodules we need to build the library
28+
- run: git submodule update --init libraries
29+
30+
# We need access to the role that is able to get CI Bot Creds
31+
- name: Configure AWS Credentials for Release
32+
uses: aws-actions/configure-aws-credentials@v2
33+
with:
34+
aws-region: us-west-2
35+
role-to-assume: arn:aws:iam::587316601012:role/GitHub-CI-CI-Bot-Credential-Access-Role-us-west-2
36+
role-session-name: CI_Bot_Release
37+
38+
- name: Upgrade Node
39+
uses: actions/setup-node@v4
40+
with:
41+
node-version: 21
42+
43+
# Use AWS Secrets Manger GHA to retrieve CI Bot Creds
44+
- name: Get CI Bot Creds Secret
45+
uses: aws-actions/aws-secretsmanager-get-secrets@v2
46+
with:
47+
secret-ids: Github/aws-crypto-tools-ci-bot
48+
parse-json-secrets: true
49+
50+
# Log in as the CI Bot
51+
- name: Log in as CI Bot
52+
run: |
53+
echo ${{env.GITHUB_AWS_CRYPTO_TOOLS_CI_BOT_ESDK_RELEASE_TOKEN}} > token.txt
54+
gh auth login --with-token < token.txt
55+
rm token.txt
56+
gh auth status
57+
58+
# Set up semantic release
59+
- name: Setup Semantic Release
60+
run: |
61+
make setup_semantic_release
62+
63+
# Run semantic release in dry run mode if input matches
64+
- name: Run Semantic Release in dry run mode
65+
env:
66+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
67+
if: ${{inputs.dry-run == 'y'}}
68+
run: |
69+
make dry_run_semantic_release
70+
71+
# Run semantic release if input matches
72+
- name: Run Semantic Release
73+
env:
74+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
75+
if: ${{inputs.dry-run == 'n'}}
76+
run: |
77+
make run_semantic_release

.releaserc.cjs

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/*
5+
First run `make setup_semantic_release` to install the required dependencies.
6+
7+
Using this config semantic-release will search for the latest tag
8+
evaluate all commits after that tag
9+
generate release notes and a version bump.
10+
It will commit these changes, push these changes, and publish a new version tag.
11+
12+
This file requires a `--branches` option to function.
13+
This is to facilitate point releases if needed.
14+
15+
`npx semantic-release --branches main`
16+
*/
17+
18+
// This project has several runtimes
19+
// each one has files that need to be updated.
20+
// We model all the files and the runtimes here in this structure
21+
const Runtimes = {
22+
java: {
23+
"project.properties": {
24+
dependencies: [],
25+
},
26+
},
27+
net: {
28+
"DynamoDbEncryption/runtimes/net/DynamoDbEncryption.csproj": {
29+
dependencies: [],
30+
assemblyInfo: "DynamoDbEncryption/runtimes/net/AssemblyInfo.cs",
31+
}
32+
},
33+
};
34+
35+
/**
36+
* @type {import('semantic-release').GlobalConfig}
37+
*/
38+
module.exports = {
39+
branches: ["main"],
40+
repositoryUrl:
41+
"[email protected]:aws/aws-database-encryption-sdk-dynamodb.git",
42+
plugins: [
43+
// Check the commits since the last release
44+
["@semantic-release/commit-analyzer",
45+
{
46+
"preset": "conventionalcommits",
47+
"parserOpts": {
48+
"noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"]
49+
},
50+
"presetConfig": {
51+
"types": [
52+
{"type": "feat", "section": "Features"},
53+
{"type": "fix", "section": "Fixes"},
54+
{"type": "chore", "section": "Maintenance"},
55+
{"type": "docs", "section": "Maintenance"},
56+
{"type": "revert", "section": "Fixes"},
57+
{"type": "style", "hidden": true},
58+
{"type": "refactor", "hidden": true},
59+
{"type": "perf", "hidden": true},
60+
{"type": "test", "hidden": true}
61+
]
62+
},
63+
"releaseRules": [
64+
{"type": "docs", "release": "patch"},
65+
{"type": "revert", "release": "patch"},
66+
{"type": "chore", "release": "patch"}
67+
]
68+
},
69+
],
70+
// Based on the commits generate release notes
71+
["@semantic-release/release-notes-generator",
72+
{
73+
"preset": "conventionalcommits",
74+
"parserOpts": {
75+
"noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"]
76+
},
77+
"presetConfig": {
78+
"types": [
79+
{"type": "feat", "section": "Features"},
80+
{"type": "fix", "section": "Fixes"},
81+
{"type": "chore", "section": "Maintenance"},
82+
{"type": "docs", "section": "Maintenance"},
83+
{"type": "revert", "section": "Fixes"},
84+
{"type": "style", "hidden": true},
85+
{"type": "refactor", "hidden": true},
86+
{"type": "perf", "hidden": true},
87+
{"type": "test", "hidden": true}
88+
]
89+
}
90+
}
91+
],
92+
// Update the change log with the generated release notes
93+
[
94+
"@semantic-release/changelog",
95+
{
96+
changelogFile: "CHANGELOG.md",
97+
changelogTitle: "# Changelog",
98+
},
99+
],
100+
101+
// Bump the various versions
102+
[
103+
"semantic-release-replace-plugin",
104+
{
105+
replacements: [
106+
// Update the version for all Gradle Java projects
107+
// Does not update the dependencies
108+
{
109+
files: Object.keys(Runtimes.java),
110+
from: "projectJavaVersion=.*",
111+
to: 'projectJavaVersion=${nextRelease.version}',
112+
results: Object.keys(Runtimes.java).map(CheckResults),
113+
countMatches: true,
114+
},
115+
// Update the version for all DotNet projects
116+
// Does not update the dependencies
117+
{
118+
files: Object.keys(Runtimes.net),
119+
from: "<Version>.*</Version>",
120+
to: "<Version>${nextRelease.version}</Version>",
121+
results: Object.keys(Runtimes.net).map(CheckResults),
122+
countMatches: true,
123+
},
124+
// Update the AssmeblyInfo.cs file of the DotNet projects
125+
...Object.entries(Runtimes.net).flatMap(
126+
([file, { assemblyInfo }]) => ({
127+
files: assemblyInfo,
128+
from: "assembly: AssemblyVersion(.*)",
129+
to: 'assembly: AssemblyVersion("${nextRelease.version}")]',
130+
results: [CheckResults(assemblyInfo)],
131+
countMatches: true,
132+
}),
133+
),
134+
],
135+
},
136+
],
137+
// Commit and push changes the changelog and versions bumps
138+
[
139+
"@semantic-release/git",
140+
{
141+
assets: [
142+
"CHANGELOG.md",
143+
...Object.values(Runtimes).flatMap((r) => Object.keys(r)),
144+
...Object.values(Runtimes.net).flatMap((r) => r.assemblyInfo),
145+
],
146+
message:
147+
"chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
148+
},
149+
],
150+
],
151+
};
152+
153+
function CheckResults(file) {
154+
return {
155+
file,
156+
hasChanged: true,
157+
numMatches: 1,
158+
numReplacements: 1,
159+
};
160+
}

Makefile

+9
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,12 @@ generate_properties_file:
5151
--namespace aws.polymorph \
5252
--properties-file $(PROJECT_ROOT)/smithy-dafny-project.properties \
5353
";
54+
55+
setup_semantic_release:
56+
npm i --no-save semantic-release @semantic-release/changelog semantic-release-replace-plugin conventional-changelog-conventionalcommits @semantic-release/git
57+
58+
run_semantic_release:
59+
npx semantic-release --no-ci
60+
61+
dry_run_semantic_release:
62+
npx semantic-release --dry-run

0 commit comments

Comments
 (0)