fix(bump-stacks): extract bun edit script to bump.js (heredoc was busted)

The inline 'cat > /tmp/bump.js <<JS' heredoc died because Gitea Actions
indents the entire run: block, and the closing 'JS' marker for an
unquoted heredoc must sit at column zero. The script never reached
disk and the action exited on a syntax error.

Move the editor into bump.js next to action.yml, reference it via
${{ github.action_path }}.
This commit is contained in:
Michael Czechowski
2026-05-05 01:11:15 +02:00
parent f1ac88259b
commit 7c2ba75c36
2 changed files with 35 additions and 32 deletions

View File

@@ -1,7 +1,8 @@
name: bump-stacks name: bump-stacks
description: | description: |
Push the new short sha for a stack into libretech/gitops-sandbox/stacks.yml. Push the new short sha for a stack into libretech/gitops-sandbox/stacks.yml.
Idempotent: a no-op when the sha is already pinned. Idempotent: a no-op when the sha is already pinned. Retries up to 3× on
non-fast-forward to absorb concurrent bumps from sibling stack repos.
inputs: inputs:
stack: stack:
@@ -32,6 +33,7 @@ runs:
RUN: ${{ inputs.run_number }} RUN: ${{ inputs.run_number }}
BOT_TOKEN: ${{ inputs.bot_token }} BOT_TOKEN: ${{ inputs.bot_token }}
SANDBOX_REPO: ${{ inputs.sandbox_repo }} SANDBOX_REPO: ${{ inputs.sandbox_repo }}
ACTION_PATH: ${{ github.action_path }}
run: | run: |
set -euo pipefail set -euo pipefail
WORK=$(mktemp -d) WORK=$(mktemp -d)
@@ -40,44 +42,15 @@ runs:
git config --global user.email "gitops-bot@librete.ch" git config --global user.email "gitops-bot@librete.ch"
REPO_URL="https://oauth2:${BOT_TOKEN}@git.librete.ch/${SANDBOX_REPO}.git" REPO_URL="https://oauth2:${BOT_TOKEN}@git.librete.ch/${SANDBOX_REPO}.git"
# Retry up to 3 times on non-fast-forward to absorb concurrent bumps.
for attempt in 1 2 3; do for attempt in 1 2 3; do
rm -rf clone rm -rf clone
git clone --depth=2 "$REPO_URL" clone git clone --depth=2 "$REPO_URL" clone
cd clone cd clone
bun --version >/dev/null # baked into runner-image
# Bun-native edit: load yaml, mutate, write back. Preserves order
# because the `yaml` package keeps key positions on round-trip.
cat > /tmp/bump.js <<'JS'
import { readFileSync, writeFileSync } from "node:fs";
import { parseDocument } from "yaml";
const [, , stack, sha, run] = process.argv;
const doc = parseDocument(readFileSync("stacks.yml", "utf8"));
const stacks = doc.get("stacks");
if (!stacks?.has(stack)) {
console.error(`stack '${stack}' not in stacks.yml`);
process.exit(2);
}
const node = stacks.get(stack);
const oldSha = node.get("sha");
if (String(oldSha) === String(sha)) {
console.log(`no-op: ${stack} already at sha=${sha}`);
process.exit(10); // sentinel for caller
}
node.set("sha", sha);
node.set("run", Number(run));
writeFileSync("stacks.yml", doc.toString());
console.log(`bumped ${stack}: ${oldSha} → ${sha}`);
JS
# Install deps inside clone (cached after first run).
[ -f package.json ] || echo '{"type":"module","dependencies":{"yaml":"^2.6.1"}}' > package.json [ -f package.json ] || echo '{"type":"module","dependencies":{"yaml":"^2.6.1"}}' > package.json
bun install --frozen-lockfile 2>/dev/null || bun install bun install --silent
set +e set +e
bun /tmp/bump.js "$STACK" "$SHA" "$RUN" bun "$ACTION_PATH/bump.js" "$STACK" "$SHA" "$RUN"
rc=$? rc=$?
set -e set -e
if [ "$rc" = "10" ]; then if [ "$rc" = "10" ]; then

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bun
// Edit stacks.yml in the gitops-sandbox checkout to pin a new sha for `stack`.
// Exit 10 = no-op (already at sha). Exit 0 = mutated, ready to commit.
import { readFileSync, writeFileSync } from "node:fs";
import { parseDocument } from "yaml";
const [, , stack, sha, run] = process.argv;
if (!stack || !sha) {
console.error("usage: bump.js <stack> <sha> <run>");
process.exit(2);
}
const doc = parseDocument(readFileSync("stacks.yml", "utf8"));
const stacks = doc.get("stacks");
if (!stacks?.has(stack)) {
console.error(`stack '${stack}' not in stacks.yml`);
process.exit(2);
}
const node = stacks.get(stack);
const oldSha = node.get("sha");
if (String(oldSha) === String(sha)) {
console.log(`no-op: ${stack} already at sha=${sha}`);
process.exit(10);
}
node.set("sha", sha);
node.set("run", Number(run ?? 0));
writeFileSync("stacks.yml", doc.toString());
console.log(`bumped ${stack}: ${oldSha}${sha}`);