diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c34449e..dea7370 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -89,7 +89,12 @@ jobs: GH_TOKEN: ${{ github.token }} CONTAINER_ENGINE: docker run: | - set -euo pipefail + set -uo pipefail + # sources.jsonl: where each package's files came from, or that the + # build failed. A failed build ends the run before any publish, and + # the record says so instead of the report job finding nothing. + : > sources.jsonl + failed=0 while read -r package arch channels publish_arches; do hash=$(git rev-parse "HEAD:pkgbuilds/$package") label="$package-$arch-$hash" @@ -99,14 +104,31 @@ jobs: mkdir -p "build-output/edge/$arch" if [[ -n "$found" ]]; then echo "==> $label: PR artifact" - curl -fsSL -H "Authorization: Bearer $GH_TOKEN" -o /tmp/artifact.zip "$found" - unzip -oq /tmp/artifact.zip -d "build-output/edge/$arch" + if curl -fsSL -H "Authorization: Bearer $GH_TOKEN" -o /tmp/artifact.zip "$found" && unzip -oq /tmp/artifact.zip -d "build-output/edge/$arch"; then + jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"pr-artifact"}' >> sources.jsonl + else + jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"artifact-download-failed"}' >> sources.jsonl; failed=1; break + fi else echo "==> $label: no artifact for this tree, building" - OMARCHY_KEEP_BUILD_WORKSPACE=1 bin/build --mirror edge --arch "$arch" --package "$package" + if OMARCHY_KEEP_BUILD_WORKSPACE=1 bin/build --mirror edge --arch "$arch" --package "$package"; then + jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"built"}' >> sources.jsonl + else + jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"build-failed"}' >> sources.jsonl; failed=1; break + fi fi done < plan.txt - ls -1 build-output/edge/*/*.pkg.tar.zst + ls -1 build-output/edge/*/*.pkg.tar.zst 2>/dev/null || true + if (( failed )); then + # Write the record now; the publish step will not run. + jq -n --arg sha "${{ github.sha }}" --arg run "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --arg prefix "${OMARCHY_PUBLISH_PREFIX:-}" --arg event "${{ github.event_name }}" \ + --slurpfile sources sources.jsonl --slurpfile plan <(jq -c '.include[]' <<<'${{ needs.changes.outputs.matrix }}' | jq -sc .) \ + '{time: (now|todate), commit:$sha, run:$run, event:$event, target: (if $prefix=="" then "live" else $prefix end), plan:$plan[0], sources:$sources, slots:[]}' \ + > publish-record.json + cat publish-record.json + exit 1 + fi - name: Publish env: @@ -184,8 +206,8 @@ jobs: done jq -n --arg sha "${{ github.sha }}" --arg run "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ --arg prefix "${OMARCHY_PUBLISH_PREFIX:-}" --arg event "${{ github.event_name }}" \ - --slurpfile slots slots.jsonl --slurpfile plan <(jq -c '.include[]' <<<'${{ needs.changes.outputs.matrix }}' | jq -sc .) \ - '{time: (now|todate), commit:$sha, run:$run, event:$event, target: (if $prefix=="" then "live" else $prefix end), plan:$plan[0], slots:$slots}' \ + --slurpfile slots slots.jsonl --slurpfile sources sources.jsonl --slurpfile plan <(jq -c '.include[]' <<<'${{ needs.changes.outputs.matrix }}' | jq -sc .) \ + '{time: (now|todate), commit:$sha, run:$run, event:$event, target: (if $prefix=="" then "live" else $prefix end), plan:$plan[0], sources:$sources, slots:$slots}' \ > publish-record.json cat publish-record.json exit $status @@ -219,12 +241,16 @@ jobs: run: | jq -r --arg outcome "${{ needs.publish.result }}" ' def pkgs: [.packages[] | select(test("-debug-")|not)] | join(", "); + def src: if .source=="pr-artifact" then "PR artifact" elif .source=="built" then "built here" else "**" + .source + "**" end; "### Publish " + (if $outcome=="success" then "succeeded" else "FAILED" end) + " → **" + .target + "**" + (if .target!="live" then " (proof prefix, not live)" else "" end), "", - (.slots[] | "- `" + .mirror + "/" + .arch + "`: " + (if .status=="published" then "" else "**" + .status + "** " end) + pkgs), + "Packages: " + ([.sources[] | .package + " (" + .arch + ", " + src + ")"] | join("; ")), "", - (if (.plan|length) > (.slots|length) then "_Some planned slots did not run because an earlier slot failed._\n" else "" end), + (if (.slots|length) > 0 then (.slots[] | "- `" + .mirror + "/" + .arch + "`: " + (if .status=="published" then "" else "**" + .status + "** " end) + pkgs) else "_Nothing was published._" end), + "", + (if ([.sources[] | select(.source|test("failed"))] | length) > 0 then "_A build failed, so no channel was touched._\n" + elif (.plan|length) > (.slots|length) then "_Some planned slots did not run because an earlier slot failed._\n" else "" end), "Commit " + .commit[0:7] + " · [run](" + .run + ")" ' publish-record.json > comment.md cat comment.md