From b5a196c99cb9d5e7e750b953e04cb803eaa27d2a Mon Sep 17 00:00:00 2001 From: Simon Dick Date: Sat, 13 Jun 2026 15:47:46 +0100 Subject: [PATCH] ci: add a manual Aminet upload workflow for failed-publish recovery When the automated Aminet upload in release.yml fails for a transient reason (FTP timeout, Aminet maintenance window, whatever) you currently have to either: - retag and re-run the whole release flow, which also re-publishes the GitHub Release with a duplicate of an already-good artefact, or - drop down to a shell and run lftp by hand against main.aminet.net. Neither is great. Add a workflow_dispatch-triggered job that takes a tag input, downloads the versioned lha + readme from that GitHub Release, renames them to the Aminet-shape unversioned form, and runs the same sidick/aminet-release-action that release.yml uses. Usage: gh workflow run "Aminet upload (manual)" -f tag=v44.0 or click "Run workflow" in the Actions tab UI. Implementation notes baked into the YAML comments: - The action's "attach to matching GitHub Release" step short-circuits on workflow_dispatch because GITHUB_REF is the branch, not the tag. Exactly what we want -- the release page already has its assets. - Files must land inside $GITHUB_WORKSPACE because the action runs in Docker and only the workspace is bind-mounted. - Permissions: contents: read is enough; we never write to the release or to the repo. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/aminet-upload.yml | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/aminet-upload.yml diff --git a/.github/workflows/aminet-upload.yml b/.github/workflows/aminet-upload.yml new file mode 100644 index 0000000..c5656ed --- /dev/null +++ b/.github/workflows/aminet-upload.yml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2026 Simon Dick + +# Manual Aminet upload. Triggered by hand from the Actions tab (or +# `gh workflow run`) when you need to push an existing GitHub Release's +# artefacts to Aminet -- typically because the automated upload in +# release.yml failed (FTP hiccup, Aminet maintenance, anything else +# transient) and you want to retry without re-tagging. +# +# The workflow downloads the versioned lha + readme from the named +# GitHub Release, renames them to the unversioned form Aminet expects, +# and runs the same aminet-release-action that release.yml uses. +# +# Notes on the action's "attach to matching GitHub Release" step here: +# workflow_dispatch sets GITHUB_REF to the dispatched branch, not the +# tag, so the action's tag-detection short-circuits and skips the +# attachment. That's the right behaviour here -- we're recovering from +# an Aminet-side problem, the GitHub Release page already has its +# assets, no need to re-upload them. + +name: Aminet upload (manual) + +on: + workflow_dispatch: + inputs: + tag: + description: >- + Release tag to upload (e.g. v44.0). Must have a matching GitHub + Release with NarratorWyomingDevice-.lha and + NarratorWyomingDevice-.readme attached. + required: true + type: string + +permissions: + contents: read # `gh release download` needs read access to release assets + +jobs: + upload: + name: Upload to Aminet + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Fetch artefacts from the named GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="${{ inputs.tag }}" + V="${TAG#v}" + mkdir -p build + gh release download "$TAG" \ + -R "$GITHUB_REPOSITORY" \ + -p "NarratorWyomingDevice-${V}.lha" \ + -p "NarratorWyomingDevice-${V}.readme" \ + --dir /tmp + # Aminet expects unversioned filenames -- the .readme's + # "Version:" field and Aminet's own slot carry the version. + # Stage them inside $GITHUB_WORKSPACE so the action's Docker + # container can see them (only the workspace gets mounted). + cp "/tmp/NarratorWyomingDevice-${V}.lha" build/NarratorWyomingDevice.lha + cp "/tmp/NarratorWyomingDevice-${V}.readme" NarratorWyomingDevice.readme + + - name: Publish to Aminet + uses: sidick/aminet-release-action@v1 + with: + filename: build/NarratorWyomingDevice.lha + readme: NarratorWyomingDevice.readme + category: util/sys