name: release on: workflow_dispatch: inputs: tag_name: description: Release tag (for example v1.0.0) required: true release_name: description: Optional release title required: false release_notes: description: Release notes / body required: false jobs: build-release: name: Build module release runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install release tooling run: | sudo apt-get update sudo apt-get install -y curl jq zip - name: Build installable module zip id: package env: MODULE_NAME: ${{ github.event.repository.name }} TAG_NAME: ${{ inputs.tag_name }} run: | set -euo pipefail tag_slug="$(printf '%s' "${TAG_NAME}" | tr '/[:space:]' '-')" archive="/tmp/${MODULE_NAME}-${tag_slug}.zip" package_root="/tmp/module-package" rm -rf "${package_root}" mkdir -p "${package_root}/${MODULE_NAME}" tar \ --exclude='./.git' \ --exclude='./.gitea' \ -C "${GITHUB_WORKSPACE}" \ -cf - . | tar -C "${package_root}/${MODULE_NAME}" -xf - cd "${package_root}" zip -qr "${archive}" "${MODULE_NAME}" ls -lh "${archive}" { echo "archive=${archive}" echo "asset_name=$(basename "${archive}")" } >> "$GITHUB_OUTPUT" - name: Create or reuse Gitea release id: release env: GITEA_TOKEN: ${{ github.token }} GITEA_API: ${{ github.server_url }}/api/v1 REPO: ${{ github.repository }} TAG_NAME: ${{ inputs.tag_name }} INPUT_RELEASE_NAME: ${{ inputs.release_name }} RELEASE_NOTES: ${{ inputs.release_notes }} TARGET_COMMITISH: ${{ github.sha }} run: | set -euo pipefail if [ -n "${INPUT_RELEASE_NAME}" ]; then release_name="${INPUT_RELEASE_NAME}" else release_name="Release ${TAG_NAME}" fi get_release_url="${GITEA_API}/repos/${REPO}/releases/tags/${TAG_NAME}" create_release_url="${GITEA_API}/repos/${REPO}/releases" status="$(curl -sS -o /tmp/release.json -w '%{http_code}' \ -H "Authorization: token ${GITEA_TOKEN}" \ "${get_release_url}")" if [ "${status}" = "200" ]; then echo "release_id=$(jq -r '.id' /tmp/release.json)" >> "$GITHUB_OUTPUT" exit 0 fi if [ "${status}" != "404" ]; then echo "Unexpected response while checking release: HTTP ${status}" cat /tmp/release.json exit 1 fi jq -n \ --arg tag_name "${TAG_NAME}" \ --arg target_commitish "${TARGET_COMMITISH}" \ --arg name "${release_name}" \ --arg body "${RELEASE_NOTES}" \ '{tag_name:$tag_name,target_commitish:$target_commitish,name:$name,body:$body,draft:false,prerelease:false}' \ > /tmp/release-payload.json curl -sS \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -X POST \ --data @/tmp/release-payload.json \ "${create_release_url}" \ -o /tmp/release.json if ! jq -e '.id' /tmp/release.json >/dev/null; then cat /tmp/release.json exit 1 fi echo "release_id=$(jq -r '.id' /tmp/release.json)" >> "$GITHUB_OUTPUT" - name: Upload release asset env: GITEA_TOKEN: ${{ github.token }} GITEA_API: ${{ github.server_url }}/api/v1 REPO: ${{ github.repository }} RELEASE_ID: ${{ steps.release.outputs.release_id }} ASSET: ${{ steps.package.outputs.archive }} ASSET_NAME: ${{ steps.package.outputs.asset_name }} run: | set -euo pipefail assets_url="${GITEA_API}/repos/${REPO}/releases/${RELEASE_ID}/assets" curl -sS \ -H "Authorization: token ${GITEA_TOKEN}" \ "${assets_url}" \ -o /tmp/release-assets.json existing_id="$(python3 - <<'PY' import json, os with open('/tmp/release-assets.json', 'r', encoding='utf-8') as f: assets = json.load(f) for asset in assets: if asset.get('name') == os.environ['ASSET_NAME']: print(asset['id']) break PY )" if [ -n "${existing_id}" ]; then curl -sS \ -H "Authorization: token ${GITEA_TOKEN}" \ -X DELETE \ "${assets_url}/${existing_id}" \ >/dev/null fi curl -sS \ -H "Authorization: token ${GITEA_TOKEN}" \ -X POST \ -F "attachment=@${ASSET}" \ "${assets_url}?name=${ASSET_NAME}" \ >/dev/null