diff --git a/.github/workflows/submit-packages.yml b/.github/workflows/submit-packages.yml index 6e888a8..b3f710b 100644 --- a/.github/workflows/submit-packages.yml +++ b/.github/workflows/submit-packages.yml @@ -56,6 +56,12 @@ jobs: V_IN: ${{ inputs.version }} run: echo "version=${V_IN#v}" >> "$GITHUB_OUTPUT" + # Chocolatey is NOT stripped here. It used to be, which meant + # distribution/chocolatey/* was templated only on the Windows job, which + # has no commit step — so those two files were the one pair that never got + # refreshed in git. This job templates every channel (and commits them); + # the chocolatey *submit* is what belongs to Windows, and the submitter + # skips itself when choco is not on PATH. - name: Resolve package managers id: pms env: @@ -63,8 +69,8 @@ jobs: run: | PMS="$PMS_IN" [ -z "$PMS" ] && PMS="all" - if [ "$PMS" = "all" ]; then PMS="homebrew,scoop,winget,aur,apt,rpm,gentoo,nix,snap,flatpak,appimage,freebsd"; fi - echo "list=$(echo "$PMS" | sed 's/chocolatey,*//g')" >> "$GITHUB_OUTPUT" + if [ "$PMS" = "all" ]; then PMS="homebrew,scoop,winget,aur,apt,rpm,gentoo,nix,chocolatey,snap,flatpak,appimage,freebsd"; fi + echo "list=$PMS" >> "$GITHUB_OUTPUT" - name: Refresh + submit manifests env: diff --git a/scripts/open-distribution-pr.sh b/scripts/open-distribution-pr.sh index e99f3e5..cda77c0 100755 --- a/scripts/open-distribution-pr.sh +++ b/scripts/open-distribution-pr.sh @@ -24,12 +24,22 @@ git config user.email "41898282+github-actions[bot]@users.noreply.github.com" BRANCH="chore/distribution-${VERSION}" # A re-run of the same release must not fail on an existing branch. +# +# --force-with-lease needs a remote-tracking ref to form its lease against. The +# release checkout is a fresh shallow clone of one ref, so refs/remotes/origin/ +# does not exist and the push is rejected with "stale info" — which is +# exactly how the first chocolatey re-run died. Fetch the branch first so the +# lease has a basis, and it behaves as intended: overwrite our own earlier +# attempt, refuse if someone else moved it. if git ls-remote --exit-code --heads origin "${BRANCH}" >/dev/null 2>&1; then echo "branch ${BRANCH} already exists on origin; force-updating it" + git fetch --depth=1 origin "+refs/heads/${BRANCH}:refs/remotes/origin/${BRANCH}" + EXPECT="$(git rev-parse "refs/remotes/origin/${BRANCH}")" git checkout -B "${BRANCH}" git add distribution git commit -m "chore(distribution): refresh manifests for v${VERSION}" - git push --force-with-lease origin "${BRANCH}" + # The lease takes the expected commit, not a ref path. + git push --force-with-lease="${BRANCH}:${EXPECT}" origin "${BRANCH}" else git checkout -b "${BRANCH}" git add distribution diff --git a/scripts/submit-packages.mjs b/scripts/submit-packages.mjs index 158d61e..ff1071f 100644 --- a/scripts/submit-packages.mjs +++ b/scripts/submit-packages.mjs @@ -255,6 +255,21 @@ function tmp(prefix) { return mkdtempSync(join(tmpdir(), `tron-${prefix}-`)); } +/** + * Is a command available on this runner? + * + * Runs the command itself rather than `which`/`where`, which differ between the + * Linux runner and the Windows one's git-bash. + */ +function hasCommand(cmd) { + try { + execFileSync(cmd, ["--version"], { stdio: "pipe" }); + return true; + } catch { + return false; + } +} + /** * Write one file into a repo we own and push it. * @@ -371,6 +386,15 @@ const SUBMITTERS = { }, chocolatey: () => { + // The Linux job templates this manifest so it gets committed with the rest; + // only the Windows job can actually pack and push it. Without this guard the + // Linux run dies on a missing `choco`. + if (!hasCommand("choco")) { + console.log( + " chocolatey: no choco on this runner, manifest refreshed — the Windows job pushes it", + ); + return; + } const key = process.env.CHOCOLATEY_API_KEY; if (!key) return skip("chocolatey", "CHOCOLATEY_API_KEY"); const dir = join(ROOT, "distribution/chocolatey");