Skip to content

Commit 91ebbbc

Browse files
committed
feat(release): attach signed jars to GitHub Releases
Add reusable setup-corretto8 and create-github-release composite actions; attach the signed jars + .asc signatures (same as Maven Central) with GPG verification notes, and add changelog + lastPublished to the RIC release.
1 parent 9bc7a4a commit 91ebbbc

5 files changed

Lines changed: 191 additions & 101 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: "Create GitHub Release with signed assets"
2+
description: >
3+
Creates a GitHub Release on an already-pushed tag. Builds the release notes
4+
from the changelog entry, a Maven Central link, and GPG verification
5+
instructions, then attaches the signed jars and their detached .asc
6+
signatures (byte-for-byte the same signatures uploaded to Maven Central). The
7+
attachment set is derived from the .asc files, so only signed, published
8+
artifacts are attached (unsigned intermediates like shade's original-*.jar are
9+
skipped). No re-signing happens here.
10+
11+
inputs:
12+
tag:
13+
description: "Git tag the release is created on (already pushed)."
14+
required: true
15+
title:
16+
description: "Release title."
17+
required: true
18+
module:
19+
description: "Module artifactId (used for the Central link and verify example)."
20+
required: true
21+
version:
22+
description: "Released version."
23+
required: true
24+
changelog-entry:
25+
description: "Markdown changelog entry used as the lead of the release notes."
26+
required: true
27+
fingerprint:
28+
description: "Public GPG key fingerprint, shown in the verification instructions."
29+
required: true
30+
artifact-dir:
31+
description: >
32+
Directory (searched non-recursively) holding the signed jars and their
33+
.asc siblings. For release:perform this is <module>/target/checkout/target;
34+
for an in-place deploy it is <module>/target.
35+
required: true
36+
extra-notes:
37+
description: "Optional Markdown inserted between the changelog and the Central link (e.g. an artifact inventory)."
38+
required: false
39+
default: ""
40+
github-token:
41+
description: "Token for the gh CLI (typically github.token)."
42+
required: true
43+
44+
runs:
45+
using: composite
46+
steps:
47+
- name: Create GitHub Release
48+
shell: bash
49+
env:
50+
GH_TOKEN: ${{ inputs.github-token }}
51+
TAG: ${{ inputs.tag }}
52+
RELEASE_TITLE: ${{ inputs.title }}
53+
REL_MODULE: ${{ inputs.module }}
54+
REL_VERSION: ${{ inputs.version }}
55+
CHANGELOG_ENTRY: ${{ inputs.changelog-entry }}
56+
GPG_FINGERPRINT: ${{ inputs.fingerprint }}
57+
ARTIFACT_DIR: ${{ inputs.artifact-dir }}
58+
EXTRA_NOTES: ${{ inputs.extra-notes }}
59+
run: |
60+
NOTES="$(mktemp)"
61+
{
62+
printf '%s\n\n' "$CHANGELOG_ENTRY"
63+
if [ -n "$EXTRA_NOTES" ]; then
64+
printf '%s\n\n' "$EXTRA_NOTES"
65+
fi
66+
echo "Published to Maven Central: https://central.sonatype.com/artifact/com.amazonaws/${REL_MODULE}/${REL_VERSION}"
67+
echo
68+
echo "## Verifying the signatures"
69+
echo
70+
echo "The attached \`.jar.asc\` files are the same GPG signatures published to Maven Central, made with the AWS Lambda Java release signing key."
71+
echo
72+
echo '```sh'
73+
echo "# Import the public signing key"
74+
echo "gpg --keyserver keys.openpgp.org --recv-keys ${GPG_FINGERPRINT}"
75+
echo "# Verify a downloaded jar against its signature"
76+
echo "gpg --verify ${REL_MODULE}-${REL_VERSION}.jar.asc ${REL_MODULE}-${REL_VERSION}.jar"
77+
echo '```'
78+
} > "$NOTES"
79+
80+
# Attach the signed jars + their detached GPG signatures. Deriving the
81+
# list from the .asc set means only signed, published artifacts are
82+
# attached (skips unsigned intermediates like shade's original-*.jar).
83+
ASSETS=()
84+
while IFS= read -r sig; do
85+
ASSETS+=("${sig%.asc}" "$sig")
86+
done < <(find "$ARTIFACT_DIR" -maxdepth 1 -type f -name '*.jar.asc' 2>/dev/null | sort)
87+
if [ ${#ASSETS[@]} -eq 0 ]; then
88+
echo "::warning::No signed jars found under $ARTIFACT_DIR; creating the release without attachments"
89+
fi
90+
91+
gh release create "$TAG" \
92+
--title "$RELEASE_TITLE" \
93+
--notes-file "$NOTES" \
94+
"${ASSETS[@]}"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: "Use the runner image's preinstalled Corretto 8"
2+
description: >
3+
Points JAVA_HOME/PATH at the CodeBuild image's preinstalled Corretto 8
4+
($JAVA_8_HOME) and writes a Maven toolchains.xml for JDK 8. The image defaults
5+
JAVA_HOME to Java 25, so this is required before any Maven call. Avoids
6+
actions/setup-java, which fetches from corretto.github.io + corretto.aws, both
7+
blocked by the runner egress lock. $JAVA_8_HOME resolves per-arch
8+
(x86_64/aarch64).
9+
10+
runs:
11+
using: composite
12+
steps:
13+
- name: Use the runner image's preinstalled Corretto 8
14+
shell: bash
15+
run: |
16+
echo "JAVA_HOME=$JAVA_8_HOME" >> "$GITHUB_ENV"
17+
echo "$JAVA_8_HOME/bin" >> "$GITHUB_PATH"
18+
"$JAVA_8_HOME/bin/java" -version
19+
mkdir -p "$HOME/.m2"
20+
cat > "$HOME/.m2/toolchains.xml" <<EOF
21+
<?xml version="1.0" encoding="UTF-8"?>
22+
<toolchains>
23+
<toolchain>
24+
<type>jdk</type>
25+
<provides><version>8</version></provides>
26+
<configuration><jdkHome>$JAVA_8_HOME</jdkHome></configuration>
27+
</toolchain>
28+
</toolchains>
29+
EOF

.github/workflows/release-runtime-interface-client.yml

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ on:
1616
description: 'Next development version override (optional, must end with -SNAPSHOT)'
1717
required: false
1818
type: string
19+
changelogEntry:
20+
description: 'Changelog entry (Markdown bullets, e.g. "- Fix X"). Prepended to the module RELEASE.CHANGELOG.md in the version-bump PR and used as the GitHub Release notes. Required.'
21+
required: true
22+
type: string
1923
skip_publish:
2024
description: 'Skip publish (dry-run validation)'
2125
required: false
@@ -38,6 +42,7 @@ env:
3842
MODULE: aws-lambda-java-runtime-interface-client
3943
RELEASE_VERSION_INPUT: ${{ github.event.inputs.releaseVersion }}
4044
DEVELOPMENT_VERSION_INPUT: ${{ github.event.inputs.developmentVersion }}
45+
CHANGELOG_ENTRY_INPUT: ${{ github.event.inputs.changelogEntry }}
4146
MAVEN_ARGS: "-B --no-transfer-progress"
4247
AWS_REGION: ${{ vars.AWS_REGION_MAVEN_RELEASE }}
4348
OIDC_ROLE_ARN: ${{ secrets.AWS_ROLE_MAVEN_RELEASE }}
@@ -75,27 +80,8 @@ jobs:
7580
7681
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
7782

78-
# Use the CodeBuild image's preinstalled Corretto 8. The image ships it at
79-
# $JAVA_8_HOME but defaults JAVA_HOME to Java 25, so point JAVA_HOME/PATH at
80-
# 8. Avoids actions/setup-java, which fetches from corretto.github.io +
81-
# corretto.aws, both blocked by the runner egress lock. $JAVA_8_HOME
82-
# resolves per-arch (x86_64/aarch64).
8383
- name: Use the runner image's preinstalled Corretto 8
84-
run: |
85-
echo "JAVA_HOME=$JAVA_8_HOME" >> "$GITHUB_ENV"
86-
echo "$JAVA_8_HOME/bin" >> "$GITHUB_PATH"
87-
"$JAVA_8_HOME/bin/java" -version
88-
mkdir -p "$HOME/.m2"
89-
cat > "$HOME/.m2/toolchains.xml" <<EOF
90-
<?xml version="1.0" encoding="UTF-8"?>
91-
<toolchains>
92-
<toolchain>
93-
<type>jdk</type>
94-
<provides><version>8</version></provides>
95-
<configuration><jdkHome>$JAVA_8_HOME</jdkHome></configuration>
96-
</toolchain>
97-
</toolchains>
98-
EOF
84+
uses: ./.github/actions/setup-corretto8
9985

10086
# Route all mvn resolution through the CodeArtifact mirror. Must precede
10187
# resolve-release-version, which invokes `mvn help:evaluate`. Ambient
@@ -164,27 +150,8 @@ jobs:
164150
with:
165151
fetch-depth: 0 # full history for tagging/pushing
166152

167-
# Use the CodeBuild image's preinstalled Corretto 8. The image ships it at
168-
# $JAVA_8_HOME but defaults JAVA_HOME to Java 25, so point JAVA_HOME/PATH at
169-
# 8. Avoids actions/setup-java, which fetches from corretto.github.io +
170-
# corretto.aws, both blocked by the runner egress lock. $JAVA_8_HOME
171-
# resolves per-arch (x86_64/aarch64).
172153
- name: Use the runner image's preinstalled Corretto 8
173-
run: |
174-
echo "JAVA_HOME=$JAVA_8_HOME" >> "$GITHUB_ENV"
175-
echo "$JAVA_8_HOME/bin" >> "$GITHUB_PATH"
176-
"$JAVA_8_HOME/bin/java" -version
177-
mkdir -p "$HOME/.m2"
178-
cat > "$HOME/.m2/toolchains.xml" <<EOF
179-
<?xml version="1.0" encoding="UTF-8"?>
180-
<toolchains>
181-
<toolchain>
182-
<type>jdk</type>
183-
<provides><version>8</version></provides>
184-
<configuration><jdkHome>$JAVA_8_HOME</jdkHome></configuration>
185-
</toolchain>
186-
</toolchains>
187-
EOF
154+
uses: ./.github/actions/setup-corretto8
188155

189156
# Route all mvn resolution through the CodeArtifact mirror. Must precede
190157
# resolve-release-version (which invokes `mvn help:evaluate`) and the OIDC
@@ -304,6 +271,10 @@ jobs:
304271
gpgconf --kill gpg-agent || true
305272
gpg --batch --import <<< "$GPG_PRIVATE_KEY"
306273
GPG_KEYNAME=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ {print $5; exit}')
274+
# Publish the primary key fingerprint (NOT secret) for the GitHub
275+
# Release verification instructions. Only the public fingerprint
276+
# crosses $GITHUB_ENV here; the passphrase and token never do.
277+
echo "GPG_FINGERPRINT=$(gpg --list-secret-keys --with-colons | awk -F: '/^fpr:/ {print $10; exit}')" >> "$GITHUB_ENV"
307278
308279
# Global settings holding only the Sonatype "central" server for upload.
309280
# Passed to Maven as -gs (global) so it MERGES with the CodeArtifact
@@ -339,10 +310,31 @@ jobs:
339310
git commit -am "chore(ric): release ${EFFECTIVE_RELEASE_VERSION}"
340311
git tag "$TAG_NAME"
341312
342-
# Next development version commit.
313+
# Next development version commit. Also refresh the informational
314+
# lastPublished marker to the version just published (rides in the
315+
# post-release commit, so the tagged release commit is untouched).
343316
mvn versions:set -DnewVersion="$NEXT_DEV_VERSION" -DgenerateBackupPoms=false --file "$MODULE/pom.xml"
317+
if grep -q "<!-- lastPublished:" "$MODULE/pom.xml"; then
318+
sed -i "s|<!-- lastPublished:.*-->|<!-- lastPublished: ${EFFECTIVE_RELEASE_VERSION} (auto-updated by release-runtime-interface-client.yml) -->|" "$MODULE/pom.xml"
319+
fi
344320
git commit -am "chore(ric): prepare next development ${NEXT_DEV_VERSION}"
345321
322+
# Prepend the changelog entry so it ships in the version-bump PR (on
323+
# top of the dev-version commit, after the tag, so the tag itself is
324+
# unchanged). Passed via env, never interpolated into the script, so
325+
# it can't inject shell.
326+
CHANGELOG="$MODULE/RELEASE.CHANGELOG.md"
327+
TMP="$(mktemp)"
328+
{
329+
echo "### $(date +'%B %d, %Y')"
330+
echo "\`${EFFECTIVE_RELEASE_VERSION}\`:"
331+
printf '%s\n\n' "$CHANGELOG_ENTRY_INPUT"
332+
[ -f "$CHANGELOG" ] && cat "$CHANGELOG"
333+
} > "$TMP"
334+
mv "$TMP" "$CHANGELOG"
335+
git add "$CHANGELOG"
336+
git commit -m "docs(release): add ${MODULE} ${EFFECTIVE_RELEASE_VERSION} changelog entry"
337+
346338
# Tag push isn't gated by branch protection; the version-bump commits
347339
# go to a release branch and land on main via PR.
348340
git push origin "refs/tags/${TAG_NAME}"
@@ -354,6 +346,24 @@ jobs:
354346
--title "chore(release): ${MODULE} ${EFFECTIVE_RELEASE_VERSION}" \
355347
--body "Post-release version bump for ${MODULE} ${EFFECTIVE_RELEASE_VERSION} (already on Maven Central, tag ${TAG_NAME} pushed)."
356348
349+
# GitHub Release on the pushed tag: the signed artifacts (byte-for-byte the
350+
# same detached GPG signatures uploaded to Maven Central) + verification
351+
# instructions. `mvn deploy` signed in place, so the jars and their .asc
352+
# siblings are in the module target dir and need no re-signing.
353+
- name: Create GitHub Release
354+
if: ${{ github.event.inputs.skip_publish != 'true' }}
355+
uses: ./.github/actions/create-github-release
356+
with:
357+
tag: ${{ env.TAG_NAME }}
358+
title: ${{ env.MODULE }} ${{ env.EFFECTIVE_RELEASE_VERSION }}
359+
module: ${{ env.MODULE }}
360+
version: ${{ env.EFFECTIVE_RELEASE_VERSION }}
361+
changelog-entry: ${{ env.CHANGELOG_ENTRY_INPUT }}
362+
fingerprint: ${{ env.GPG_FINGERPRINT }}
363+
artifact-dir: ${{ env.MODULE }}/target
364+
extra-notes: "Artifacts: main JAR + linux/linux_musl x x86_64/aarch_64 native classifier JARs."
365+
github-token: ${{ github.token }}
366+
357367
# Dry-run: validate assembly, no publish/push.
358368
- name: Dry-run assemble (no publish)
359369
if: ${{ github.event.inputs.skip_publish == 'true' }}

.github/workflows/release.yml

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -91,27 +91,8 @@ jobs:
9191
with:
9292
fetch-depth: 0 # full history for tagging/pushing
9393

94-
# Use the CodeBuild image's preinstalled Corretto 8. The image ships it at
95-
# $JAVA_8_HOME but defaults JAVA_HOME to Java 25, so point JAVA_HOME/PATH at
96-
# 8. Avoids actions/setup-java, which fetches from corretto.github.io +
97-
# corretto.aws, both blocked by the runner egress lock. $JAVA_8_HOME
98-
# resolves per-arch (x86_64/aarch64).
9994
- name: Use the runner image's preinstalled Corretto 8
100-
run: |
101-
echo "JAVA_HOME=$JAVA_8_HOME" >> "$GITHUB_ENV"
102-
echo "$JAVA_8_HOME/bin" >> "$GITHUB_PATH"
103-
"$JAVA_8_HOME/bin/java" -version
104-
mkdir -p "$HOME/.m2"
105-
cat > "$HOME/.m2/toolchains.xml" <<EOF
106-
<?xml version="1.0" encoding="UTF-8"?>
107-
<toolchains>
108-
<toolchain>
109-
<type>jdk</type>
110-
<provides><version>8</version></provides>
111-
<configuration><jdkHome>$JAVA_8_HOME</jdkHome></configuration>
112-
</toolchain>
113-
</toolchains>
114-
EOF
95+
uses: ./.github/actions/setup-corretto8
11596

11697
# Route all mvn resolution through the CodeArtifact mirror. Runs before the
11798
# OIDC step (which would shadow the runner-role creds this needs) and on
@@ -320,47 +301,22 @@ jobs:
320301
--title "chore(release): ${MODULE} ${EFFECTIVE_RELEASE_VERSION}" \
321302
--body "Post-release version bump for ${MODULE} ${EFFECTIVE_RELEASE_VERSION} (already on Maven Central, tag ${TAG} pushed)."
322303
323-
# GitHub Release on the pushed tag: changelog entry + Central link.
304+
# GitHub Release on the pushed tag: changelog + Central link + GPG verify
305+
# instructions, with the signed jars and their .asc signatures attached.
306+
# release:perform builds in a fresh checkout, so the signed artifacts live
307+
# under <module>/target/checkout/target.
324308
- name: Create GitHub Release
325309
if: ${{ github.event.inputs.skip_publish != 'true' }}
326-
env:
327-
GH_TOKEN: ${{ github.token }}
328-
run: |
329-
TAG="${MODULE}-${EFFECTIVE_RELEASE_VERSION}"
330-
NOTES="$(mktemp)"
331-
{
332-
printf '%s\n\n' "$CHANGELOG_ENTRY_INPUT"
333-
echo "Published to Maven Central: https://central.sonatype.com/artifact/com.amazonaws/${MODULE}/${EFFECTIVE_RELEASE_VERSION}"
334-
echo
335-
echo "## Verifying the signatures"
336-
echo
337-
echo "The attached \`.jar.asc\` files are the same PGP signatures published to Maven Central, made with the AWS Lambda Java release signing key."
338-
echo
339-
echo '```'
340-
echo "# 1. Import the public signing key"
341-
echo "gpg --keyserver keys.openpgp.org --recv-keys ${GPG_FINGERPRINT}"
342-
echo "# 2. Verify a downloaded jar against its signature"
343-
echo "gpg --verify ${MODULE}-${EFFECTIVE_RELEASE_VERSION}.jar.asc ${MODULE}-${EFFECTIVE_RELEASE_VERSION}.jar"
344-
echo '```'
345-
} > "$NOTES"
346-
347-
# Attach the signed jars and their detached PGP signatures produced by
348-
# release:perform (byte-for-byte the same artifacts and .asc files
349-
# Maven Central received). They live in the perform checkout's target/
350-
# dir and persist past the Release step, so no re-signing is needed.
351-
ARTIFACT_DIR="$MODULE/target/checkout/target"
352-
ASSETS=()
353-
while IFS= read -r f; do ASSETS+=("$f"); done < <(
354-
find "$ARTIFACT_DIR" -maxdepth 1 -type f \( -name '*.jar' -o -name '*.jar.asc' \) 2>/dev/null | sort
355-
)
356-
if [ ${#ASSETS[@]} -eq 0 ]; then
357-
echo "::warning::No signed jars found under $ARTIFACT_DIR; creating the release without attachments"
358-
fi
359-
360-
gh release create "$TAG" \
361-
--title "${MODULE} ${EFFECTIVE_RELEASE_VERSION}" \
362-
--notes-file "$NOTES" \
363-
"${ASSETS[@]}"
310+
uses: ./.github/actions/create-github-release
311+
with:
312+
tag: ${{ env.MODULE }}-${{ env.EFFECTIVE_RELEASE_VERSION }}
313+
title: ${{ env.MODULE }} ${{ env.EFFECTIVE_RELEASE_VERSION }}
314+
module: ${{ env.MODULE }}
315+
version: ${{ env.EFFECTIVE_RELEASE_VERSION }}
316+
changelog-entry: ${{ env.CHANGELOG_ENTRY_INPUT }}
317+
fingerprint: ${{ env.GPG_FINGERPRINT }}
318+
artifact-dir: ${{ env.MODULE }}/target/checkout/target
319+
github-token: ${{ github.token }}
364320

365321
- name: Dry-run release (prepare only, no publish)
366322
if: ${{ github.event.inputs.skip_publish == 'true' }}

aws-lambda-java-runtime-interface-client/pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.amazonaws</groupId>
66
<artifactId>aws-lambda-java-runtime-interface-client</artifactId>
7-
<version>2.12.0-SNAPSHOT</version>
7+
<version>2.12.1-SNAPSHOT</version>
8+
<!-- lastPublished: 2.12.0 (auto-updated by release-runtime-interface-client.yml) -->
89
<packaging>jar</packaging>
910

1011
<name>AWS Lambda Java Runtime Interface Client</name>

0 commit comments

Comments
 (0)