Skip to content

Commit 035edf9

Browse files
committed
Fix package release workflows
Simplify package release dispatches so release workflows always publish the current origin/main after attesting the latest matching package preflight, instead of duplicating preflight SHA overrides and publish checkboxes. Harden Android R8 preflight setup by making the runtime script own emulator image/AVD creation, use pipefail-safe sdkmanager prompts, force a single AVD home, and verify the AVD is visible before starting the emulator. Update release-readiness assertions and the local checker pin for the corrected workflow contract.
1 parent 2774b34 commit 035edf9

8 files changed

Lines changed: 47 additions & 112 deletions

.github/workflows/crates-release.yml

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,12 @@ name: Crates.io Release
66

77
on:
88
workflow_dispatch:
9-
inputs:
10-
release_sha:
11-
description: Optional exact main commit SHA. Leave blank to use the current origin/main SHA.
12-
required: false
13-
type: string
14-
default: ""
15-
publish:
16-
description: Publish crates to crates.io after the dry run succeeds
17-
required: true
18-
type: boolean
19-
default: false
209

2110
permissions:
2211
contents: read
2312

2413
concurrency:
25-
group: crates-release-${{ inputs.release_sha || github.ref_name }}
14+
group: crates-release-main
2615
cancel-in-progress: false
2716

2817
jobs:
@@ -42,21 +31,11 @@ jobs:
4231
ref: main
4332
fetch-depth: 0
4433

45-
- name: Resolve release SHA
34+
- name: Resolve current release SHA
4635
id: resolve-release-sha
47-
env:
48-
RELEASE_SHA_INPUT: ${{ inputs.release_sha }}
4936
run: |
5037
git fetch --no-tags origin main
51-
if [ -n "${RELEASE_SHA_INPUT}" ]; then
52-
if [[ ! "${RELEASE_SHA_INPUT}" =~ ^[0-9a-f]{40}$ ]]; then
53-
echo "::error::release_sha must be blank or a lowercase 40-character commit SHA"
54-
exit 1
55-
fi
56-
release_sha="${RELEASE_SHA_INPUT}"
57-
else
58-
release_sha="$(git rev-parse origin/main)"
59-
fi
38+
release_sha="$(git rev-parse origin/main)"
6039
if [ "$(git rev-parse origin/main)" != "${release_sha}" ]; then
6140
echo "::error::resolved release SHA is not the current origin/main tip"
6241
exit 1
@@ -120,7 +99,6 @@ jobs:
12099
publish:
121100
name: publish crates
122101
needs: [verify-release-sha, dry-run]
123-
if: inputs.publish == true
124102
runs-on: ubuntu-latest
125103
permissions:
126104
actions: read

.github/workflows/kotlin-android-package-preflight.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,9 @@ jobs:
187187

188188
- name: Install Android NDK
189189
run: |
190-
yes | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;29.0.14206865"
190+
{ yes || true; } | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;29.0.14206865"
191191
echo "ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/29.0.14206865" >> "${GITHUB_ENV}"
192192
193-
- name: Install Android emulator image
194-
run: |
195-
yes | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "emulator" "platforms;android-36" "system-images;android-36;google_apis;x86_64"
196-
echo "no" | "${ANDROID_HOME}/cmdline-tools/latest/bin/avdmanager" create avd --force -n reallyme-r8-gate -k "system-images;android-36;google_apis;x86_64" --device "pixel"
197-
198193
- name: Stage Android JNI libraries
199194
run: scripts/build_android_native_resources.sh build/android-jniLibs
200195

.github/workflows/kotlin-android-package-release.yml

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,11 @@ name: Kotlin Android Package Release
77
on:
88
workflow_dispatch:
99
inputs:
10-
release_sha:
11-
description: Optional exact main commit SHA. Leave blank to use the current origin/main SHA.
12-
required: false
13-
type: string
14-
default: ""
1510
version:
1611
description: Release version without leading v
1712
required: true
1813
type: string
1914
default: 0.2.0
20-
publish:
21-
description: Publish the JVM jar and Android AAR to Maven
22-
required: true
23-
type: boolean
24-
default: false
2515

2616
permissions:
2717
contents: read
@@ -46,21 +36,11 @@ jobs:
4636
ref: main
4737
fetch-depth: 0
4838

49-
- name: Resolve release SHA
39+
- name: Resolve current release SHA
5040
id: resolve-release-sha
51-
env:
52-
RELEASE_SHA_INPUT: ${{ inputs.release_sha }}
5341
run: |
5442
git fetch --no-tags origin main
55-
if [ -n "${RELEASE_SHA_INPUT}" ]; then
56-
if [[ ! "${RELEASE_SHA_INPUT}" =~ ^[0-9a-f]{40}$ ]]; then
57-
echo "::error::release_sha must be blank or a lowercase 40-character commit SHA"
58-
exit 1
59-
fi
60-
release_sha="${RELEASE_SHA_INPUT}"
61-
else
62-
release_sha="$(git rev-parse origin/main)"
63-
fi
43+
release_sha="$(git rev-parse origin/main)"
6444
if [ "$(git rev-parse origin/main)" != "${release_sha}" ]; then
6545
echo "::error::resolved release SHA is not the current origin/main tip"
6646
exit 1
@@ -185,7 +165,6 @@ jobs:
185165
run: ./gradlew test publishToMavenLocal -Preallyme.codec.nativeResourcesDir=${{ github.workspace }}/build/kotlin-native-resources -Preallyme.codec.requireFullNativeResources=true
186166

187167
- name: Publish Maven artifact
188-
if: inputs.publish == true
189168
working-directory: packages/kotlin
190169
run: |
191170
node ../../scripts/verify_release_attestation.mjs
@@ -235,7 +214,7 @@ jobs:
235214

236215
- name: Install Android NDK
237216
run: |
238-
yes | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;29.0.14206865"
217+
{ yes || true; } | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;29.0.14206865"
239218
echo "ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/29.0.14206865" >> "${GITHUB_ENV}"
240219
241220
- name: Stage Android JNI libraries
@@ -248,7 +227,6 @@ jobs:
248227
run: packages/kotlin/gradlew -p packages/kotlin-android bundleReleaseAar verifyReleaseAarContainsJniLibs -Preallyme.codec.androidJniLibsDir=${{ github.workspace }}/build/android-jniLibs -Preallyme.codec.androidNativeAssetsDir=${{ github.workspace }}/build/android-native-assets -Preallyme.codec.requireAndroidJniLibs=true
249228

250229
- name: Publish Android AAR
251-
if: inputs.publish == true
252230
run: |
253231
node scripts/verify_release_attestation.mjs
254232
packages/kotlin/gradlew -p packages/kotlin-android publish -Preallyme.codec.androidJniLibsDir=${{ github.workspace }}/build/android-jniLibs -Preallyme.codec.androidNativeAssetsDir=${{ github.workspace }}/build/android-native-assets -Preallyme.codec.requireAndroidJniLibs=true

.github/workflows/npm-package-release.yml

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,11 @@ name: npm Package Release
77
on:
88
workflow_dispatch:
99
inputs:
10-
release_sha:
11-
description: Optional exact main commit SHA. Leave blank to use the current origin/main SHA.
12-
required: false
13-
type: string
14-
default: ""
1510
version:
1611
description: Release version without leading v
1712
required: true
1813
type: string
1914
default: 0.2.0
20-
publish:
21-
description: Publish the TypeScript package to npm
22-
required: true
23-
type: boolean
24-
default: false
2515

2616
permissions:
2717
contents: read
@@ -46,21 +36,11 @@ jobs:
4636
ref: main
4737
fetch-depth: 0
4838

49-
- name: Resolve release SHA
39+
- name: Resolve current release SHA
5040
id: resolve-release-sha
51-
env:
52-
RELEASE_SHA_INPUT: ${{ inputs.release_sha }}
5341
run: |
5442
git fetch --no-tags origin main
55-
if [ -n "${RELEASE_SHA_INPUT}" ]; then
56-
if [[ ! "${RELEASE_SHA_INPUT}" =~ ^[0-9a-f]{40}$ ]]; then
57-
echo "::error::release_sha must be blank or a lowercase 40-character commit SHA"
58-
exit 1
59-
fi
60-
release_sha="${RELEASE_SHA_INPUT}"
61-
else
62-
release_sha="$(git rev-parse origin/main)"
63-
fi
43+
release_sha="$(git rev-parse origin/main)"
6444
if [ "$(git rev-parse origin/main)" != "${release_sha}" ]; then
6545
echo "::error::resolved release SHA is not the current origin/main tip"
6646
exit 1
@@ -141,7 +121,6 @@ jobs:
141121
working-directory: packages/ts
142122

143123
- name: Publish npm package
144-
if: inputs.publish == true
145124
run: |
146125
if [ -z "${NODE_AUTH_TOKEN}" ]; then
147126
echo "::error::NPM_TOKEN is required"

.github/workflows/swift-package-release.yml

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,11 @@ name: Swift Package Release
77
on:
88
workflow_dispatch:
99
inputs:
10-
release_sha:
11-
description: Optional exact main commit SHA. Leave blank to use the current origin/main SHA.
12-
required: false
13-
type: string
14-
default: ""
1510
version:
1611
description: Release version without leading v
1712
required: true
1813
type: string
1914
default: 0.2.0
20-
publish:
21-
description: Create the SwiftPM GitHub release and upload the xcframework
22-
required: true
23-
type: boolean
24-
default: false
2515

2616
permissions:
2717
contents: read
@@ -46,21 +36,11 @@ jobs:
4636
ref: main
4737
fetch-depth: 0
4838

49-
- name: Resolve release SHA
39+
- name: Resolve current release SHA
5040
id: resolve-release-sha
51-
env:
52-
RELEASE_SHA_INPUT: ${{ inputs.release_sha }}
5341
run: |
5442
git fetch --no-tags origin main
55-
if [ -n "${RELEASE_SHA_INPUT}" ]; then
56-
if [[ ! "${RELEASE_SHA_INPUT}" =~ ^[0-9a-f]{40}$ ]]; then
57-
echo "::error::release_sha must be blank or a lowercase 40-character commit SHA"
58-
exit 1
59-
fi
60-
release_sha="${RELEASE_SHA_INPUT}"
61-
else
62-
release_sha="$(git rev-parse origin/main)"
63-
fi
43+
release_sha="$(git rev-parse origin/main)"
6444
if [ "$(git rev-parse origin/main)" != "${release_sha}" ]; then
6545
echo "::error::resolved release SHA is not the current origin/main tip"
6646
exit 1
@@ -154,7 +134,6 @@ jobs:
154134
swift-release:
155135
name: SwiftPM release tag
156136
needs: [verify-release-sha, swift-artifact, swift-verify]
157-
if: inputs.publish == true
158137
runs-on: ubuntu-latest
159138
permissions:
160139
actions: read

scripts/check_release_readiness.mjs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,8 +1764,9 @@ for (const workflowPath of packagePreflightWorkflows) {
17641764
}
17651765
for (const workflowPath of packageReleaseWorkflows) {
17661766
assertContains(workflowPath, "Verify reviewed release SHA");
1767-
assertContains(workflowPath, "Resolve release SHA");
1768-
assertContains(workflowPath, 'default: ""');
1767+
assertContains(workflowPath, "Resolve current release SHA");
1768+
assertNotContains(workflowPath, "RELEASE_SHA_INPUT");
1769+
assertNotContains(workflowPath, "inputs.publish");
17691770
}
17701771
assertContains(".github/workflows/kotlin-android-package-release.yml", "Write native checksum manifest");
17711772
assertContains(".github/workflows/kotlin-android-package-preflight.yml", "Write native checksum manifest");
@@ -1820,8 +1821,7 @@ assertNotContains(".github/workflows/kotlin-android-package-release.yml", "publi
18201821
assertNotContains(".github/workflows/npm-package-release.yml", "publish_swift:");
18211822
assertNotContains(".github/workflows/npm-package-release.yml", "publish_maven:");
18221823
assertContains(".github/workflows/crates-release.yml", "Verify reviewed release SHA");
1823-
assertContains(".github/workflows/crates-release.yml", "Resolve release SHA");
1824-
assertContains(".github/workflows/crates-release.yml", 'default: ""');
1824+
assertContains(".github/workflows/crates-release.yml", "Resolve current release SHA");
18251825
assertContains(".github/workflows/crates-release.yml", "release_version:");
18261826
assertContains(".github/workflows/crates-release.yml", "crates/codec/Cargo.toml");
18271827
assertContains(".github/workflows/crates-release.yml", "RELEASE_VERSION=${release_version}");
@@ -2618,10 +2618,21 @@ assertContains("packages/kotlin-android/consumer-r8-runtime/src/main/java/me/rea
26182618
assertContains("scripts/test_android_consumer_r8_runtime.sh", ":consumer-r8-runtime:assembleRelease");
26192619
assertContains("scripts/test_android_consumer_r8_runtime.sh", "logcat");
26202620
assertContains("scripts/test_android_consumer_r8_runtime.sh", "ensure_avd_exists");
2621+
assertContains("scripts/test_android_consumer_r8_runtime.sh", "ANDROID_AVD_HOME_VALUE");
2622+
assertContains("scripts/test_android_consumer_r8_runtime.sh", "export ANDROID_AVD_HOME");
26212623
assertContains("scripts/test_android_consumer_r8_runtime.sh", "$EMULATOR\" -list-avds");
26222624
assertContains("scripts/test_android_consumer_r8_runtime.sh", "{ yes || true; } | \"$SDKMANAGER\"");
2625+
assertContains("scripts/test_android_consumer_r8_runtime.sh", "Android AVD was not available after creation");
26232626
assertContains("scripts/test_android_consumer_r8_runtime.sh", "$AVDMANAGER\" create avd --force");
26242627
assertContains("scripts/test_android_consumer_r8_runtime.sh", "Android consumer R8 runtime gate passed");
2628+
assertContains(
2629+
".github/workflows/kotlin-android-package-preflight.yml",
2630+
'{ yes || true; } | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;29.0.14206865"',
2631+
);
2632+
assertContains(
2633+
".github/workflows/kotlin-android-package-release.yml",
2634+
'{ yes || true; } | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;29.0.14206865"',
2635+
);
26252636
assertContains("packages/kotlin-android/README.md", "me.really:codec-android:0.2.0");
26262637
assertContains("packages/kotlin-android/README.md", "never sourced from the Git worktree");
26272638
assertContains(
@@ -2654,12 +2665,12 @@ assertContains(".github/workflows/kotlin-android-package-preflight.yml", "Write
26542665
assertContains(".github/workflows/kotlin-android-package-release.yml", "verifyReleaseAarContainsJniLibs");
26552666
assertContains(".github/workflows/kotlin-android-package-release.yml", "RELEASE_VERSION");
26562667
assertContains(".github/workflows/swift-package-release.yml", "needs: [verify-release-sha, swift-artifact]");
2657-
assertContains(".github/workflows/swift-package-release.yml", "if: inputs.publish == true");
2658-
assertContains(".github/workflows/kotlin-android-package-release.yml", "if: inputs.publish == true");
2659-
assertContains(".github/workflows/npm-package-release.yml", "if: inputs.publish == true");
2668+
assertNotContains(".github/workflows/swift-package-release.yml", "if: inputs.publish == true");
2669+
assertNotContains(".github/workflows/kotlin-android-package-release.yml", "if: inputs.publish == true");
2670+
assertNotContains(".github/workflows/npm-package-release.yml", "if: inputs.publish == true");
26602671
assertContains(".github/workflows/kotlin-android-package-preflight.yml", "android aar preflight");
26612672
assertContains(".github/workflows/kotlin-android-package-preflight.yml", "requireAndroidJniLibs=true");
2662-
assertContains(".github/workflows/kotlin-android-package-preflight.yml", "Install Android emulator image");
2673+
assertNotContains(".github/workflows/kotlin-android-package-preflight.yml", "Install Android emulator image");
26632674
assertContains(".github/workflows/kotlin-android-package-preflight.yml", "Test Android consumer R8 runtime");
26642675
assertContains(".github/workflows/kotlin-android-package-preflight.yml", "REALLYME_CODEC_ANDROID_AVD: reallyme-r8-gate");
26652676
assertContains(".github/workflows/kotlin-android-package-preflight.yml", "timeout-minutes: 15");

scripts/run_pinned_release_readiness.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const RELEASE_READINESS_COMMIT = "f27973caf9d3a12847cac4032c361f5f553c97e9";
1515
const RELEASE_READINESS_CORE_SHA256 =
1616
"70cc78721738cf352024938e8fc86e73380e71b2cdf7a9a733687543167cbaae";
1717
const LOCAL_CHECKER_SHA256 =
18-
"180a48848b11ce86655b1910e1db1acc8d3e870c1d059712a22347aa692383fe";
18+
"7d6ae80d98bb5bf8a84ce928f5224f55bb62c956a4f587a1311c0be51aae31f1";
1919
const RELEASE_READINESS_CORE_URL =
2020
`https://raw.githubusercontent.com/reallyme/release-readiness/${RELEASE_READINESS_COMMIT}/core.mjs`;
2121
const VENDORED_CORE_PATH = "scripts/release-readiness/core.mjs";

scripts/test_android_consumer_r8_runtime.sh

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ readonly ADB="${ADB:-"$ANDROID_HOME_VALUE/platform-tools/adb"}"
1212
readonly EMULATOR="${EMULATOR:-"$ANDROID_HOME_VALUE/emulator/emulator"}"
1313
readonly SDKMANAGER="${SDKMANAGER:-"$ANDROID_HOME_VALUE/cmdline-tools/latest/bin/sdkmanager"}"
1414
readonly AVDMANAGER="${AVDMANAGER:-"$ANDROID_HOME_VALUE/cmdline-tools/latest/bin/avdmanager"}"
15+
readonly ANDROID_AVD_HOME_VALUE="${ANDROID_AVD_HOME:-"$HOME/.android/avd"}"
1516
readonly AVD_NAME="${REALLYME_CODEC_ANDROID_AVD:-}"
1617
readonly ANDROID_R8_PLATFORM="platforms;android-36"
1718
readonly ANDROID_R8_SYSTEM_IMAGE="system-images;android-36;google_apis;x86_64"
@@ -23,6 +24,7 @@ readonly NATIVE_ASSETS_DIR="$REPO_ROOT/build/android-native-assets"
2324
readonly APK_PATH="$REPO_ROOT/packages/kotlin-android/consumer-r8-runtime/build/outputs/apk/release/consumer-r8-runtime-release.apk"
2425

2526
emulator_pid=""
27+
export ANDROID_AVD_HOME="$ANDROID_AVD_HOME_VALUE"
2628

2729
cleanup() {
2830
if [[ -n "$emulator_pid" ]]; then
@@ -44,6 +46,7 @@ fail() {
4446
}
4547

4648
ensure_avd_exists() {
49+
mkdir -p "$ANDROID_AVD_HOME_VALUE"
4750
local avd_exists="false"
4851
while IFS= read -r existing_avd; do
4952
if [[ "$existing_avd" == "$AVD_NAME" ]]; then
@@ -59,7 +62,19 @@ ensure_avd_exists() {
5962
[[ -x "$SDKMANAGER" ]] || fail "Android sdkmanager is required at $SDKMANAGER"
6063
[[ -x "$AVDMANAGER" ]] || fail "Android avdmanager is required at $AVDMANAGER"
6164
{ yes || true; } | "$SDKMANAGER" "emulator" "$ANDROID_R8_PLATFORM" "$ANDROID_R8_SYSTEM_IMAGE" >/dev/null
62-
echo "no" | "$AVDMANAGER" create avd --force -n "$AVD_NAME" -k "$ANDROID_R8_SYSTEM_IMAGE" --device "pixel" >/dev/null
65+
printf 'no\n' | "$AVDMANAGER" create avd --force -n "$AVD_NAME" -k "$ANDROID_R8_SYSTEM_IMAGE" --device "pixel" >/tmp/reallyme-codec-r8-avdmanager.log
66+
67+
while IFS= read -r existing_avd; do
68+
if [[ "$existing_avd" == "$AVD_NAME" ]]; then
69+
return
70+
fi
71+
done < <("$EMULATOR" -list-avds)
72+
73+
if [[ -f /tmp/reallyme-codec-r8-avdmanager.log ]]; then
74+
cat /tmp/reallyme-codec-r8-avdmanager.log >&2 || true
75+
fi
76+
"$EMULATOR" -list-avds >&2 || true
77+
fail "Android AVD was not available after creation"
6378
}
6479

6580
[[ -x "$ADB" ]] || fail "adb is required at $ADB"

0 commit comments

Comments
 (0)