Skip to content

Commit 2fe77ab

Browse files
chore(go): Add Go release workflow and script (#1958)
1 parent 9825a4c commit 2fe77ab

File tree

3 files changed

+242
-0
lines changed

3 files changed

+242
-0
lines changed

.github/workflows/go-release.yml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: Go Release Automation
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
project-name:
7+
description: "Project name (e.g., DynamoDbEncryption)"
8+
required: true
9+
type: string
10+
version:
11+
description: "Version (e.g., v0.1.0)"
12+
required: true
13+
type: string
14+
15+
jobs:
16+
get-dafny-version:
17+
uses: ./.github/workflows/dafny_version.yml
18+
19+
go-release:
20+
needs: get-dafny-version
21+
runs-on: macos-13
22+
permissions:
23+
contents: write
24+
pull-requests: write
25+
id-token: write
26+
27+
steps:
28+
- name: Support longpaths on Git checkout
29+
run: |
30+
git config --global core.longpaths true
31+
32+
# KMS and MPL tests need to use credentials which can call KMS
33+
- name: Configure AWS Credentials
34+
uses: aws-actions/configure-aws-credentials@v4
35+
with:
36+
aws-region: us-west-2
37+
role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-DDBEC-Dafny-Role-us-west-2
38+
role-session-name: GoRelease-DBESDK-Tests
39+
40+
- name: Checkout repository
41+
uses: actions/checkout@v4
42+
with:
43+
fetch-depth: 0
44+
token: ${{ secrets.GITHUB_TOKEN }}
45+
46+
- name: Update submodules
47+
run: |
48+
git submodule update --init --recursive
49+
50+
- name: Setup Dafny
51+
uses: dafny-lang/[email protected]
52+
with:
53+
dafny-version: ${{ needs.get-dafny-version.outputs.version }}
54+
55+
- name: Install Go
56+
uses: actions/setup-go@v5
57+
with:
58+
go-version: "1.23"
59+
60+
- name: Install Go imports
61+
run: |
62+
go install golang.org/x/tools/cmd/goimports@latest
63+
64+
- name: Install Smithy-Dafny codegen dependencies
65+
uses: ./.github/actions/install_smithy_dafny_codegen_dependencies
66+
67+
- name: Configure Git
68+
run: |
69+
git config --global user.name "GitHub Actions"
70+
git config --global user.email "[email protected]"
71+
72+
- name: Get release directory name
73+
id: release-dir
74+
run: |
75+
chmod +x ./scripts/go-release-automation.sh
76+
RELEASE_DIR_NAME=$(./scripts/go-release-automation.sh get_release_dir_name "${{ github.event.inputs.project-name }}" "${{ github.event.inputs.version }}")
77+
echo "releaseDirName=$RELEASE_DIR_NAME" >> $GITHUB_OUTPUT
78+
79+
- name: Generate a changelog
80+
uses: orhun/git-cliff-action@v4
81+
with:
82+
config: releases/go/.git-cliff.toml
83+
args: --bump -u --prepend releases/go/${{ steps.release-dir.outputs.releaseDirName }}/CHANGELOG.md
84+
85+
- name: Run Go release automation script
86+
run: |
87+
chmod +x ./scripts/go-release-automation.sh
88+
./scripts/go-release-automation.sh run_release_script ${{ github.event.inputs.project-name }} ${{ github.event.inputs.version }}
89+
90+
- name: Create Pull Request
91+
env:
92+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93+
run: |
94+
PROJECT_NAME="${{ github.event.inputs.project-name }}"
95+
VERSION="${{ github.event.inputs.version }}"
96+
97+
# Get the release directory name using the sourced function
98+
RELEASE_DIR_NAME="${{ steps.release-dir.outputs.releaseDirName }}"
99+
100+
BRANCH_NAME="golang-release-staging-branch/$RELEASE_DIR_NAME/$VERSION"
101+
102+
DIFF_FILES=$(diff -qr $PROJECT_NAME/runtimes/go/ImplementationFromDafny-go releases/go/$RELEASE_DIR_NAME || true)
103+
104+
# Create PR using GitHub CLI
105+
gh pr create \
106+
--title "chore(go): Release $RELEASE_DIR_NAME Go module $VERSION" \
107+
--body "This PR was automatically created by the Go Release Automation workflow. It releases version $VERSION of the $RELEASE_DIR_NAME Go module. The diff between $PROJECT_NAME/runtimes/go/ImplementationFromDafny-go and releases/go/$RELEASE_DIR_NAME is below:
108+
109+
$DIFF_FILES
110+
" \
111+
--base main \
112+
--head "$BRANCH_NAME" \
113+
--label "golang" \
114+
--draft

releases/go/.git-cliff.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[git]
2+
tag_pattern = "^releases/go/mpl/v*"
3+
filter_commits = true
4+
commit_parsers = [
5+
{ message = '^feat\((go|all languages)\)', group = "Features"},
6+
{ message = '^fix\((go|all languages)\)', group = "Fixes"},
7+
{ message = '^chore\((go|all languages)\)', group = "Maintenance"},
8+
{ message = '^docs\((go|all languages)\)', group = "Maintenance"},
9+
{ message = '^revert\((go|all languages)\)', group = "Fixes"},
10+
{ message = '^style\((go|all languages)\)', group = "Miscellaneous"},
11+
{ message = '^refactor\((go|all languages)\)', group = "Miscellaneous"},
12+
{ message = '^perf\((go|all languages)\)', group = "Miscellaneous"},
13+
{ message = '^test\((go|all languages)\)', group = "Miscellaneous"},
14+
]
15+
commit_preprocessors = [
16+
{ pattern = '\(dafny\)', replace = '(all languages)'}
17+
]
18+
19+
[changelog]
20+
header = "# Changelog\n\n"
21+
trim = true

scripts/go-release-automation.sh

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/bin/bash
2+
3+
# Go Release Process Script
4+
# Used for copying go files to release directory and make a commit
5+
6+
set -e # Exit on error
7+
8+
# Check if project name and version is provided
9+
if [ $# -ne 3 ]; then
10+
echo "Usage: $0 <function> <project-name> [version]"
11+
echo "Example: $0 get_release_dir_name DynamoDbEncryption v0.1.0"
12+
echo "Example: $0 run_release_script DynamoDbEncryption v0.1.0"
13+
exit 1
14+
fi
15+
16+
# Function to map project name to release directory name
17+
get_release_dir_name() {
18+
local project=$1
19+
case "$project" in
20+
"DynamoDbEncryption") echo "dynamodb-esdk" ;;
21+
*) echo "Error: Unknown project name: $project" >&2; return 1 ;;
22+
esac
23+
}
24+
25+
run_release_script() {
26+
PROJECT_NAME=$1
27+
VERSION=$2
28+
29+
echo "Starting Go release script for $PROJECT_NAME $VERSION"
30+
31+
# Pull the latest smithy-dafny and libraries git submodules
32+
echo " Pulling latest git submodules..."
33+
git submodule update --init --recursive
34+
35+
# Go to the project directory
36+
echo " Navigating to $PROJECT_NAME..."
37+
cd "$PROJECT_NAME" || { echo "Error: Project directory $PROJECT_NAME not found"; exit 1; }
38+
39+
# Build using make commands
40+
echo " Building project..."
41+
make polymorph_dafny
42+
make polymorph_go
43+
make transpile_go
44+
make test_go
45+
46+
# Run Go tools in ImplementationFromDafny-go
47+
echo " Running Go tools in ImplementationFromDafny-go..."
48+
cd runtimes/go/ImplementationFromDafny-go || { echo "Error: ImplementationFromDafny-go directory not found"; exit 1; }
49+
50+
find . -name "*shim.go" -type f -delete
51+
echo "Removed all shim.go files"
52+
53+
echo "Running goimports..."
54+
goimports -w .
55+
56+
echo "Running go get -u..."
57+
go get -u
58+
59+
echo "Running go mod tidy..."
60+
go mod tidy
61+
62+
echo "Running go build to check for errors..."
63+
go build --gcflags="-e" ./...
64+
65+
# Replacement directives are removed to get package from go pkg instead of local copy
66+
echo "Removing all replace directives from go.mod..."
67+
go mod edit -json | jq -r '.Replace[].Old.Path' | xargs -n1 go mod edit -dropreplace
68+
69+
# Get the mapped release directory name
70+
RELEASE_DIR_NAME=$(get_release_dir_name "$PROJECT_NAME")
71+
72+
# Copy files to releases directory
73+
echo " Copying files to releases/go/$RELEASE_DIR_NAME..."
74+
75+
# Use rsync to copy files while excluding following ones:
76+
# ImplementationFromDafny.go: This file is for devlopment. Users is expected use API(s) from `*/api_client.go`
77+
# ImplementationFromDafny-go.dtr: This is the dafny translation record only needed for code generation
78+
# go.sum: This files will be updated by go mod tidy
79+
rsync -av --exclude="ImplementationFromDafny.go" --exclude="ImplementationFromDafny-go.dtr" --exclude="go.sum" ./ "$(git rev-parse --show-toplevel)/releases/go/$RELEASE_DIR_NAME/"
80+
81+
# Run Go tools in releases directory
82+
echo "Running Go tools in releases/go/$RELEASE_DIR_NAME..."
83+
84+
cd "$(git rev-parse --show-toplevel)/releases/go/$RELEASE_DIR_NAME/" || { echo "Error: releases directory not found"; exit 1; }
85+
86+
echo "Running goimports..."
87+
goimports -w .
88+
echo "Running go get -u..."
89+
go get -u ./...
90+
91+
echo "Running go mod tidy..."
92+
go mod tidy
93+
94+
echo "Running go build to check for errors..."
95+
go build --gcflags="-e" ./...
96+
97+
# Prepare for commit
98+
echo "creating a branch..."
99+
100+
git checkout -b "golang-release-staging-branch/$RELEASE_DIR_NAME/${VERSION}"
101+
git add *
102+
103+
git commit -m "Release $RELEASE_DIR_NAME Go module ${VERSION}"
104+
git push origin "golang-release-staging-branch/$RELEASE_DIR_NAME/${VERSION}"
105+
}
106+
107+
"$@"

0 commit comments

Comments
 (0)