diff --git a/.gitea/workflows/release-tool.yml b/.gitea/workflows/release-tool.yml new file mode 100644 index 0000000..261f776 --- /dev/null +++ b/.gitea/workflows/release-tool.yml @@ -0,0 +1,124 @@ +name: Release Tool + +on: + push: + tags: + - "v*" + +jobs: + release: + runs-on: self-hosted + env: + CHECKOUT_PATH: ${{ vars.SOW_TOOLS_CHECKOUT_PATH }} + + steps: + - name: Sync tools checkout to tag + env: + TAG_NAME: ${{ github.ref_name }} + run: | + set -euo pipefail + CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}" + cd "${CHECKOUT_PATH}" + git fetch origin --prune --tags + git reset --hard "${TAG_NAME}" + git clean -fd + + - name: Build nwn-tool + run: | + set -euo pipefail + CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}" + cd "${CHECKOUT_PATH}" + ./build-tool.sh + + - name: Pack release bundle + id: pack + env: + TAG_NAME: ${{ github.ref_name }} + run: | + set -euo pipefail + CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}" + cd "${CHECKOUT_PATH}" + binary="tools/nwn-tool" + if [[ ! -x "${binary}" ]]; then + echo "Missing built tool: ${binary}" + exit 1 + fi + archive="/tmp/nwn-tool-linux-amd64-${TAG_NAME}.tar.gz" + tar -czf "${archive}" -C tools nwn-tool + echo "archive=${archive}" >> "$GITHUB_OUTPUT" + echo "asset_name=nwn-tool-linux-amd64.tar.gz" >> "$GITHUB_OUTPUT" + echo "tag=${TAG_NAME}" >> "$GITHUB_OUTPUT" + + - name: Create release and upload artifact + env: + GITEA_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITEA_SERVER_URL: ${{ github.server_url }} + GITEA_REPO: ${{ github.repository }} + ARCHIVE: ${{ steps.pack.outputs.archive }} + ASSET_NAME: ${{ steps.pack.outputs.asset_name }} + TAG_NAME: ${{ steps.pack.outputs.tag }} + run: | + set -euo pipefail + API="${GITEA_SERVER_URL%/}/api/v1" + OWNER="${GITEA_REPO%%/*}" + NAME="${GITEA_REPO#*/}" + AUTH=(-H "Authorization: token ${GITEA_API_TOKEN}" -H "Accept: application/json") + RESP_FILE=/tmp/gitea-release.json + + CODE=$(curl -sS -o "${RESP_FILE}" -w "%{http_code}" "${AUTH[@]}" \ + "${API}/repos/${OWNER}/${NAME}/releases/tags/${TAG_NAME}") + + if [[ "${CODE}" == "200" ]]; then + RELEASE_ID=$(jq -r '.id' "${RESP_FILE}") + else + BODY=$(jq -n --arg t "${TAG_NAME}" \ + '{tag_name: $t, name: $t, body: "nwn-tool binary release built by Gitea Actions."}') + CODE=$(curl -sS -o "${RESP_FILE}" -w "%{http_code}" "${AUTH[@]}" \ + -X POST -H "Content-Type: application/json" \ + -d "${BODY}" \ + "${API}/repos/${OWNER}/${NAME}/releases") + if [[ "${CODE}" != "201" && "${CODE}" != "200" ]]; then + echo "Create release failed (HTTP ${CODE}):" + cat "${RESP_FILE}" + exit 1 + fi + RELEASE_ID=$(jq -r '.id' "${RESP_FILE}") + fi + + ASSET_ID=$(jq -r --arg name "${ASSET_NAME}" '.assets[]? | select(.name == $name) | .id' "${RESP_FILE}" | head -n1) + if [[ -n "${ASSET_ID}" ]]; then + curl -sS -f "${AUTH[@]}" -X DELETE \ + "${API}/repos/${OWNER}/${NAME}/releases/${RELEASE_ID}/assets/${ASSET_ID}" + fi + + curl -sS -f "${AUTH[@]}" -X POST \ + -F "attachment=@${ARCHIVE}" \ + "${API}/repos/${OWNER}/${NAME}/releases/${RELEASE_ID}/assets?name=${ASSET_NAME}" + + - name: Cleanup temporary files + if: always() + env: + TAG_NAME: ${{ github.ref_name }} + run: | + rm -f "/tmp/nwn-tool-linux-amd64-${TAG_NAME}.tar.gz" /tmp/gitea-release.json + + - name: Prune old releases (keep latest 1) + env: + GITEA_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITEA_SERVER_URL: ${{ github.server_url }} + GITEA_REPO: ${{ github.repository }} + run: | + set -euo pipefail + API="${GITEA_SERVER_URL%/}/api/v1" + OWNER="${GITEA_REPO%%/*}" + NAME="${GITEA_REPO#*/}" + AUTH=(-H "Authorization: token ${GITEA_API_TOKEN}" -H "Accept: application/json") + curl -sS "${AUTH[@]}" \ + "${API}/repos/${OWNER}/${NAME}/releases?limit=50&page=1" \ + -o /tmp/all-releases.json + jq -r '.[1:][].id' /tmp/all-releases.json | while read -r rid; do + [[ -n "${rid}" ]] || continue + curl -sS -f "${AUTH[@]}" -X DELETE \ + "${API}/repos/${OWNER}/${NAME}/releases/${rid}" + done + rm -f /tmp/all-releases.json diff --git a/README.md b/README.md index 7475356..9619222 100644 --- a/README.md +++ b/README.md @@ -37,3 +37,8 @@ tools/ built development binary output - `sow-assets` uses `nwn-tool` for `build-haks` and validation During development, sibling repositories can point at `../sow-tools/tools/nwn-tool`. For pinned releases, each consumer repo can instead carry its own copy at `tools/nwn-tool`. + + +## Release Automation + +This repo publishes a Linux `nwn-tool` release artifact through Gitea Actions as `nwn-tool-linux-amd64.tar.gz`. Consumer repos can fetch that binary into their local `tools/` directory with their `install-tool.sh` helper.