ci-actions/forgejo-release/action.yml
2026-06-06 14:44:53 +01:00

78 lines
3.2 KiB
YAML

name: Publish a Forgejo release
description: >-
Create (or replace) a release on this Forgejo instance and upload assets,
using the Forgejo API via curl. Reimplements forgejo-release / the
hand-rolled curl uploads — no marketplace actions.
inputs:
token:
description: API token with write access (e.g. secrets.FORGEJO_PACKAGE_TOKEN or the workflow token).
required: true
files:
description: A directory (all regular files within are uploaded) or a glob of asset files.
required: true
tag:
description: Release tag. Defaults to the pushed ref name (github.ref_name).
default: ""
draft:
description: Create the release as a draft ("true"/"false").
default: "false"
prerelease:
description: Mark the release as a prerelease ("true"/"false").
default: "false"
override:
description: >-
Delete any existing release (and its tag) with the same tag first, then recreate it
at the current commit. Use for moving tags such as "latest".
default: "false"
runs:
using: composite
steps:
- name: Create release and upload assets
shell: bash
env:
TOKEN: ${{ inputs.token }}
FILES: ${{ inputs.files }}
IN_TAG: ${{ inputs.tag }}
DRAFT: ${{ inputs.draft }}
PRERELEASE: ${{ inputs.prerelease }}
OVERRIDE: ${{ inputs.override }}
SERVER_URL: ${{ github.server_url }}
REPO: ${{ github.repository }}
REF_NAME: ${{ github.ref_name }}
SHA: ${{ github.sha }}
run: |
set -euo pipefail
command -v jq >/dev/null 2>&1 || { apt-get update && apt-get install -y --no-install-recommends jq curl; }
tag="${IN_TAG:-$REF_NAME}"
api="${SERVER_URL}/api/v1/repos/${REPO}"
auth=(-H "Authorization: token ${TOKEN}")
# Override: remove an existing release+tag so a moving tag (e.g. latest) is recreated cleanly.
if [ "$OVERRIDE" = "true" ]; then
rid="$(curl -fsS "${auth[@]}" "${api}/releases/tags/${tag}" 2>/dev/null | jq -r '.id // empty' || true)"
[ -n "$rid" ] && curl -fsS -X DELETE "${auth[@]}" "${api}/releases/${rid}" >/dev/null 2>&1 || true
curl -fsS -X DELETE "${auth[@]}" "${api}/tags/${tag}" >/dev/null 2>&1 || true
fi
# Create the release. target_commitish pins a not-yet-existing tag to this commit.
payload="$(jq -nc --arg t "$tag" --arg c "$SHA" \
--argjson d "$DRAFT" --argjson p "$PRERELEASE" \
'{tag_name:$t, name:$t, target_commitish:$c, draft:$d, prerelease:$p}')"
rid="$(curl -fsS -X POST "${auth[@]}" -H "Content-Type: application/json" \
"${api}/releases" -d "$payload" | jq -r '.id')"
echo "Created release ${tag} (id ${rid})"
# Collect assets: a directory expands to its contents, otherwise treat the input as a glob.
shopt -s nullglob
if [ -d "$FILES" ]; then set -- "$FILES"/*; else set -- $FILES; fi
for f in "$@"; do
[ -f "$f" ] || continue
name="$(basename "$f")"
curl -fsS -X POST "${auth[@]}" \
"${api}/releases/${rid}/assets?name=${name}" \
-F "attachment=@${f};type=application/octet-stream" >/dev/null
echo "uploaded ${name}"
done