Skip to content

Commit e642159

Browse files
committed
ci: allow re-using engine builds for releases
1 parent fc89662 commit e642159

File tree

5 files changed

+169
-27
lines changed

5 files changed

+169
-27
lines changed

.github/workflows/release.yaml

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ on:
1212
required: true
1313
type: boolean
1414
default: true
15+
reuse_engine_version:
16+
description: 'Reuse engine artifacts from this version (skips building)'
17+
required: false
18+
type: string
1519

1620
defaults:
1721
run:
@@ -75,6 +79,7 @@ jobs:
7579
binaries:
7680
name: "Build & Push Binaries"
7781
needs: [setup]
82+
if: ${{ !inputs.reuse_engine_version }}
7883
strategy:
7984
matrix:
8085
include:
@@ -158,6 +163,7 @@ jobs:
158163
docker:
159164
name: "Build & Push Docker Images"
160165
needs: [setup]
166+
if: ${{ !inputs.reuse_engine_version }}
161167
strategy:
162168
matrix:
163169
include:
@@ -223,7 +229,8 @@ jobs:
223229

224230
complete:
225231
name: "Complete"
226-
needs: [docker, binaries]
232+
needs: [setup, docker, binaries]
233+
if: ${{ always() && !cancelled() && needs.setup.result == 'success' && (needs.docker.result == 'success' || needs.docker.result == 'skipped') && (needs.binaries.result == 'success' || needs.binaries.result == 'skipped') }}
227234
runs-on: ubuntu-24.04
228235
steps:
229236
- uses: actions/checkout@v4
@@ -259,8 +266,15 @@ jobs:
259266
# Install tsx globally
260267
npm install -g tsx
261268
262-
if [ "${{ inputs.latest }}" = "true" ]; then
263-
./scripts/release/main.ts --version "${{ github.event.inputs.version }}" --phase complete-ci --no-validate-git
264-
else
265-
./scripts/release/main.ts --version "${{ github.event.inputs.version }}" --no-latest --phase complete-ci --no-validate-git
269+
# Build command based on inputs
270+
CMD="./scripts/release/main.ts --version \"${{ github.event.inputs.version }}\" --phase complete-ci --no-validate-git"
271+
272+
if [ "${{ inputs.latest }}" != "true" ]; then
273+
CMD="$CMD --no-latest"
266274
fi
275+
276+
if [ -n "${{ inputs.reuse_engine_version }}" ]; then
277+
CMD="$CMD --reuse-engine-version \"${{ inputs.reuse_engine_version }}\""
278+
fi
279+
280+
eval "$CMD"

scripts/release/artifacts.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,27 @@ export async function updateArtifacts(opts: ReleaseOpts) {
3434
AWS_DEFAULT_REGION: "auto",
3535
};
3636

37+
// Determine which commit to use for source artifacts
38+
let sourceCommit = opts.commit;
39+
if (opts.reuseEngineVersion) {
40+
console.log(`==> Reusing artifacts from version ${opts.reuseEngineVersion}`);
41+
const result = await $`git rev-parse v${opts.reuseEngineVersion}`;
42+
sourceCommit = result.stdout.trim().slice(0, 7);
43+
console.log(`==> Source commit: ${sourceCommit}`);
44+
}
45+
3746
// List all files under engine/{commit}/
38-
const commitPrefix = `engine/${opts.commit}/`;
47+
const commitPrefix = `engine/${sourceCommit}/`;
3948
console.log(`==> Listing Original Files: ${commitPrefix}`);
4049
const listResult = await $({
4150
env: awsEnv,
4251
shell: true,
52+
stdio: ["pipe", "pipe", "inherit"],
4353
})`aws s3api list-objects --bucket rivet-releases --prefix ${commitPrefix} --endpoint-url ${endpointUrl}`;
4454
const commitFiles = JSON.parse(listResult.stdout);
4555
assert(
4656
Array.isArray(commitFiles?.Contents) && commitFiles.Contents.length > 0,
47-
`No files found under engine/${opts.commit}/`,
57+
`No files found under engine/${sourceCommit}/`,
4858
);
4959

5060
// Copy files to version directory
@@ -71,13 +81,15 @@ async function copyFiles(
7181
await $({
7282
env: awsEnv,
7383
shell: true,
84+
stdio: "inherit",
7485
})`aws s3 rm s3://rivet-releases/${targetPrefix} --recursive --endpoint-url ${endpointUrl}`;
7586

7687
// Copy new files using --recursive
7788
console.log(`Copying files from ${sourcePrefix} to ${targetPrefix}`);
7889
await $({
7990
env: awsEnv,
8091
shell: true,
92+
stdio: "inherit",
8193
})`aws s3 cp s3://rivet-releases/${sourcePrefix} s3://rivet-releases/${targetPrefix} --recursive --copy-props none --endpoint-url ${endpointUrl}`;
8294
}
8395

@@ -104,6 +116,7 @@ async function generateInstallScripts(
104116
env: awsEnv,
105117
input: scriptContent,
106118
shell: true,
119+
stdio: ["pipe", "inherit", "inherit"],
107120
})`aws s3 cp - s3://rivet-releases/${uploadKey} --endpoint-url ${endpointUrl}`;
108121
}
109122
}

scripts/release/docker.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,48 @@ export async function tagDocker(opts: {
99
version: string;
1010
commit: string;
1111
latest: boolean;
12+
reuseEngineVersion?: string;
1213
}) {
14+
// Determine which commit to use for source images
15+
let sourceCommit = opts.commit;
16+
if (opts.reuseEngineVersion) {
17+
console.log(`==> Reusing artifacts from version ${opts.reuseEngineVersion}`);
18+
const result = await $`git rev-parse v${opts.reuseEngineVersion}`;
19+
sourceCommit = result.stdout.trim().slice(0, 7);
20+
console.log(`==> Source commit: ${sourceCommit}`);
21+
}
22+
1323
for (const { name, prefix, main } of REPOS) {
1424
// Check both architecture images exist using manifest inspect
15-
console.log(`==> Checking images exist: ${name}:${prefix}-${opts.commit}-{amd64,arm64}`);
25+
console.log(`==> Checking images exist: ${name}:${prefix}-${sourceCommit}-{amd64,arm64}`);
1626
try {
17-
console.log(`==> Inspecting ${name}:${prefix}-${opts.commit}-amd64`);
18-
await $`docker manifest inspect ${name}:${prefix}-${opts.commit}-amd64`;
19-
console.log(`==> Inspecting ${name}:${prefix}-${opts.commit}-arm64`);
20-
await $`docker manifest inspect ${name}:${prefix}-${opts.commit}-arm64`;
27+
console.log(`==> Inspecting ${name}:${prefix}-${sourceCommit}-amd64`);
28+
await $({ stdio: "inherit" })`docker manifest inspect ${name}:${prefix}-${sourceCommit}-amd64`;
29+
console.log(`==> Inspecting ${name}:${prefix}-${sourceCommit}-arm64`);
30+
await $({ stdio: "inherit" })`docker manifest inspect ${name}:${prefix}-${sourceCommit}-arm64`;
2131
console.log(`==> Both images exist`);
2232
} catch (error) {
2333
console.error(`==> Error inspecting images:`, error);
2434
throw new Error(
25-
`Images ${name}:${prefix}-${opts.commit}-{amd64,arm64} do not exist on Docker Hub. Error: ${error}`,
35+
`Images ${name}:${prefix}-${sourceCommit}-{amd64,arm64} do not exist on Docker Hub. Error: ${error}`,
2636
);
2737
}
2838

2939
// Create and push manifest with version
3040
await createManifest(
3141
name,
32-
`${prefix}-${opts.commit}`,
42+
`${prefix}-${sourceCommit}`,
3343
`${prefix}-${opts.version}`,
3444
);
3545
if (main) {
36-
await createManifest(name, `${prefix}-${opts.commit}`, opts.version);
46+
await createManifest(name, `${prefix}-${sourceCommit}`, opts.version);
3747
}
3848

3949
// Create and push manifest with latest
4050
if (opts.latest) {
41-
await createManifest(name, `${prefix}-${opts.commit}`, `${prefix}-latest`);
51+
await createManifest(name, `${prefix}-${sourceCommit}`, `${prefix}-latest`);
4252
if (main) {
43-
await createManifest(name, `${prefix}-${opts.commit}`, "latest");
53+
await createManifest(name, `${prefix}-${sourceCommit}`, "latest");
4454
}
4555
}
4656
}
@@ -51,5 +61,5 @@ async function createManifest(image: string, from: string, to: string) {
5161

5262
// Use buildx imagetools to create and push multi-arch manifest
5363
// This works with manifest lists as inputs (unlike docker manifest create)
54-
await $`docker buildx imagetools create --tag ${image}:${to} ${image}:${from}-amd64 ${image}:${from}-arm64`;
64+
await $({ stdio: "inherit" })`docker buildx imagetools create --tag ${image}:${to} ${image}:${from}-amd64 ${image}:${from}-arm64`;
5565
}

scripts/release/git.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ export async function createAndPushTag(opts: ReleaseOpts) {
1616
console.log(`Creating tag v${opts.version}...`);
1717
try {
1818
// Create tag and force update if it exists
19-
await $({ cwd: opts.root })`git tag -f v${opts.version}`;
19+
await $({ stdio: "inherit", cwd: opts.root })`git tag -f v${opts.version}`;
2020

2121
// Push tag with force to ensure it's updated
22-
await $({ cwd: opts.root })`git push origin v${opts.version} -f`;
22+
await $({ stdio: "inherit", cwd: opts.root })`git push origin v${opts.version} -f`;
2323

2424
console.log(`✅ Tag v${opts.version} created and pushed`);
2525
} catch (err) {
@@ -54,19 +54,22 @@ export async function createGitHubRelease(opts: ReleaseOpts) {
5454
`Updating release ${opts.version} to point to new tag ${tagName}`,
5555
);
5656
await $({
57+
stdio: "inherit",
5758
cwd: opts.root,
5859
})`gh release edit ${existingRelease.tagName} --tag ${tagName}`;
5960
} else {
6061
console.log(
6162
`Creating new release ${opts.version} pointing to tag ${tagName}`,
6263
);
6364
await $({
65+
stdio: "inherit",
6466
cwd: opts.root,
6567
})`gh release create ${tagName} --title ${opts.version} --generate-notes`;
6668

6769
// Check if this is a pre-release (contains -rc. or similar)
6870
if (opts.version.includes("-")) {
6971
await $({
72+
stdio: "inherit",
7073
cwd: opts.root,
7174
})`gh release edit ${tagName} --prerelease`;
7275
}

0 commit comments

Comments
 (0)