Compare commits

..

1 Commits

Author SHA1 Message Date
argoyle f2f0b69479 Merge pull request 'chore: Configure Renovate' (#1) from renovate/configure into main
Reviewed-on: #1
2026-01-08 19:20:36 +00:00
5 changed files with 237 additions and 244 deletions
-12
View File
@@ -1,12 +0,0 @@
{
"permissions": {
"allow": [
"Bash(but --help:*)",
"Bash(but rub --help:*)",
"WebSearch",
"WebFetch(domain:docs.gitea.com)",
"WebFetch(domain:gitea.com)",
"Bash(but status:*)"
]
}
}
+232 -186
View File
@@ -8,51 +8,47 @@ on:
required: false required: false
default: false default: false
type: boolean type: boolean
secrets:
concurrency: UNBOUND_RELEASE_TOKEN:
group: release-${{ github.repository }} description: 'Token with API access to create PRs and releases'
cancel-in-progress: false required: true
env: env:
GITEA_URL: http://gitea-http.gitea.svc.cluster.local:3000 GITEA_URL: https://git.unbound.se
RELEASE_TOKEN_FILE: /runner-secrets/release-token
GIT_CLIFF_VERSION: "2.12.0"
jobs: jobs:
preconditions: preconditions:
name: Check Preconditions name: Check Preconditions
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: amd64/alpine:3.22.2@sha256:b687e78c6e2785808446f45b52f1540a1e58adc07bdcffea354933b18c613d90
steps: steps:
- name: Validate token - name: Validate token
if: ${{ secrets.UNBOUND_RELEASE_TOKEN == '' }}
run: | run: |
if [ ! -r "${RELEASE_TOKEN_FILE}" ]; then echo "To use Unbound Release, a UNBOUND_RELEASE_TOKEN secret needs to be defined."
echo "Release token file not found at ${RELEASE_TOKEN_FILE}" echo "It needs API access to write repository files, create PRs and releases."
echo "This workflow requires the runner to have RELEASE_TOKEN configured." echo " "
exit 1 echo "Create a token in Gitea: Settings -> Applications -> Generate New Token"
fi echo "Required scopes: repository (read/write), issue (read/write)"
if [ ! -s "${RELEASE_TOKEN_FILE}" ]; then exit 1
echo "Release token file is empty"
exit 1
fi
echo "Release token found"
changelog-and-pr: changelog:
name: Generate Changelog and Handle PR name: Generate Changelog
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: preconditions needs: preconditions
if: github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch if: github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch
container:
image: orhunp/git-cliff:2.10.1@sha256:6ba0d1fcb051bd7b154cfb19c4b2b3bfa2c22c475f5285fc30606777b6573119
outputs:
version: ${{ steps.version.outputs.version }}
has_changes: ${{ steps.check.outputs.has_changes }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install git-cliff
run: |
curl -sSfL "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-gnu.tar.gz" | tar xz
sudo mv "git-cliff-${GIT_CLIFF_VERSION}/git-cliff" /usr/local/bin/
git-cliff --version
- name: Generate changelog - name: Generate changelog
run: | run: |
git-cliff --bump --unreleased --strip header > CHANGES.md git-cliff --bump --unreleased --strip header > CHANGES.md
@@ -76,40 +72,63 @@ jobs:
echo "has_changes=true" >> $GITHUB_OUTPUT echo "has_changes=true" >> $GITHUB_OUTPUT
fi fi
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: changelog-artifacts
path: |
CHANGES.md
CHANGELOG.md
VERSION
handle-pr:
name: Handle Release PR
runs-on: ubuntu-latest
needs: changelog
if: needs.changelog.outputs.has_changes == 'true'
container:
image: amd64/alpine:3.22.2@sha256:b687e78c6e2785808446f45b52f1540a1e58adc07bdcffea354933b18c613d90
steps:
- name: Install dependencies
run: apk add --no-cache git jq curl
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: changelog-artifacts
- name: Create or update release PR - name: Create or update release PR
if: steps.check.outputs.has_changes == 'true'
env: env:
TOKEN: ${{ secrets.UNBOUND_RELEASE_TOKEN }}
REPOSITORY: ${{ github.repository }} REPOSITORY: ${{ github.repository }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: | run: |
TOKEN=$(cat "${RELEASE_TOKEN_FILE}")
VERSION=$(cat VERSION) VERSION=$(cat VERSION)
OWNER=$(echo "${REPOSITORY}" | cut -d'/' -f1) OWNER=$(echo "${REPOSITORY}" | cut -d'/' -f1)
REPO=$(echo "${REPOSITORY}" | cut -d'/' -f2) REPO=$(echo "${REPOSITORY}" | cut -d'/' -f2)
API_URL="${GITEA_URL}/api/v1/repos/${OWNER}/${REPO}" API_URL="${GITEA_URL}/api/v1/repos/${OWNER}/${REPO}"
# Fallback to main if DEFAULT_BRANCH is empty
BASE_BRANCH="${DEFAULT_BRANCH:-main}"
echo "Using base branch: ${BASE_BRANCH}"
TITLE="chore(release): prepare for ${VERSION}" TITLE="chore(release): prepare for ${VERSION}"
# Read CHANGES.md content and add note (jq --arg will handle JSON escaping) # Read CHANGES.md and escape for JSON
CHANGES_CONTENT=$(cat CHANGES.md) DESCRIPTION=$(cat CHANGES.md | jq -Rs .)
PR_NOTE="**Note:** Please use **Squash Merge** when merging this PR." DESCRIPTION="${DESCRIPTION:1:-1}" # Remove surrounding quotes from jq
DESCRIPTION="${CHANGES_CONTENT}"$'\n\n---\n\n'"${PR_NOTE}"
# Delete existing next-release branch to start fresh (auto-closes any open PR) # Add squash merge reminder
echo "Checking for existing next-release branch..." DESCRIPTION="${DESCRIPTION}
BRANCH_CHECK=$(curl -s --retry 3 --retry-delay 2 --retry-connrefused -w "%{http_code}" -o /dev/null \
---
**Note:** Please use **Squash Merge** when merging this PR."
echo "Checking for existing release PRs..."
PRS=$(curl -sf \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
"${API_URL}/branches/next-release") "${API_URL}/pulls?state=open" | jq '[.[] | select(.head.ref == "next-release")]')
if [ "${BRANCH_CHECK}" = "200" ]; then PR_INDEX=$(echo "${PRS}" | jq -r '.[0].number // empty')
echo "Deleting existing next-release branch..."
curl -sf --retry 3 --retry-delay 2 --retry-connrefused -X DELETE \ echo "Checking for existing next-release branch..."
-H "Authorization: token ${TOKEN}" \ BRANCH_EXISTS=$(curl -sf \
"${API_URL}/branches/next-release" -H "Authorization: token ${TOKEN}" \
echo "Branch deleted" "${API_URL}/branches/next-release" 2>/dev/null && echo "true" || echo "false")
fi
# Prepare CHANGELOG.md content # Prepare CHANGELOG.md content
CHANGELOG_CONTENT=$(base64 -w0 < CHANGELOG.md) CHANGELOG_CONTENT=$(base64 -w0 < CHANGELOG.md)
@@ -118,66 +137,81 @@ jobs:
VERSION_JSON=$(jq -n --arg v "${VERSION}" '{"version":$v}') VERSION_JSON=$(jq -n --arg v "${VERSION}" '{"version":$v}')
VERSION_CONTENT=$(echo "${VERSION_JSON}" | base64 -w0) VERSION_CONTENT=$(echo "${VERSION_JSON}" | base64 -w0)
echo "Creating new next-release branch from ${BASE_BRANCH}..." if [ "${BRANCH_EXISTS}" = "true" ]; then
echo "Updating existing next-release branch..."
# Check if CHANGELOG.md exists on base branch to determine create vs update # Get SHA of existing CHANGELOG.md
CHANGELOG_SHA=$(curl -sf --retry 3 --retry-delay 2 --retry-connrefused \ CHANGELOG_SHA=$(curl -sf \
-H "Authorization: token ${TOKEN}" \
"${API_URL}/contents/CHANGELOG.md?ref=${BASE_BRANCH}" | jq -r '.sha // empty')
if [ -n "${CHANGELOG_SHA}" ]; then
echo "Updating CHANGELOG.md (exists on ${BASE_BRANCH}) on new branch..."
RESPONSE=$(curl -s --retry 3 --retry-delay 2 --retry-connrefused -w "\n%{http_code}" -X PUT \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \ "${API_URL}/contents/CHANGELOG.md?ref=next-release" | jq -r '.sha // empty')
--data "$(jq -n \
--arg content "${CHANGELOG_CONTENT}" \ # Update or create CHANGELOG.md
--arg sha "${CHANGELOG_SHA}" \ if [ -n "${CHANGELOG_SHA}" ]; then
--arg message "${TITLE}" \ curl -sf -X PUT \
--arg branch "${BASE_BRANCH}" \ -H "Authorization: token ${TOKEN}" \
--arg new_branch "next-release" \ -H "Content-Type: application/json" \
'{content: $content, sha: $sha, message: $message, branch: $branch, new_branch: $new_branch}')" \ --data "$(jq -n \
"${API_URL}/contents/CHANGELOG.md") --arg content "${CHANGELOG_CONTENT}" \
--arg sha "${CHANGELOG_SHA}" \
--arg message "${TITLE}" \
--arg branch "next-release" \
'{content: $content, sha: $sha, message: $message, branch: $branch}')" \
"${API_URL}/contents/CHANGELOG.md"
else
curl -sf -X POST \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
--data "$(jq -n \
--arg content "${CHANGELOG_CONTENT}" \
--arg message "${TITLE}" \
--arg branch "next-release" \
'{content: $content, message: $message, branch: $branch, new_branch: $branch}')" \
"${API_URL}/contents/CHANGELOG.md"
fi
# Get SHA of existing .version
VERSION_SHA=$(curl -sf \
-H "Authorization: token ${TOKEN}" \
"${API_URL}/contents/.version?ref=next-release" | jq -r '.sha // empty')
# Update or create .version
if [ -n "${VERSION_SHA}" ]; then
curl -sf -X PUT \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
--data "$(jq -n \
--arg content "${VERSION_CONTENT}" \
--arg sha "${VERSION_SHA}" \
--arg message "${TITLE}" \
--arg branch "next-release" \
'{content: $content, sha: $sha, message: $message, branch: $branch}')" \
"${API_URL}/contents/.version"
else
curl -sf -X POST \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
--data "$(jq -n \
--arg content "${VERSION_CONTENT}" \
--arg message "${TITLE}" \
--arg branch "next-release" \
'{content: $content, message: $message, branch: $branch}')" \
"${API_URL}/contents/.version"
fi
else else
echo "Creating CHANGELOG.md on new branch..." echo "Creating new next-release branch with CHANGELOG.md..."
RESPONSE=$(curl -s --retry 3 --retry-delay 2 --retry-connrefused -w "\n%{http_code}" -X POST \ curl -sf -X POST \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--data "$(jq -n \ --data "$(jq -n \
--arg content "${CHANGELOG_CONTENT}" \ --arg content "${CHANGELOG_CONTENT}" \
--arg message "${TITLE}" \ --arg message "${TITLE}" \
--arg branch "${BASE_BRANCH}" \
--arg new_branch "next-release" \
'{content: $content, message: $message, branch: $branch, new_branch: $new_branch}')" \
"${API_URL}/contents/CHANGELOG.md")
fi
HTTP_CODE=$(echo "${RESPONSE}" | tail -1)
BODY=$(echo "${RESPONSE}" | sed '$d')
if [ "${HTTP_CODE}" -ge 400 ]; then
echo "Error with CHANGELOG.md: ${BODY}"
exit 1
fi
# Check if .version exists on base branch
VERSION_SHA=$(curl -sf --retry 3 --retry-delay 2 --retry-connrefused \
-H "Authorization: token ${TOKEN}" \
"${API_URL}/contents/.version?ref=${BASE_BRANCH}" | jq -r '.sha // empty')
if [ -n "${VERSION_SHA}" ]; then
echo "Updating .version on next-release branch..."
curl -sf --retry 3 --retry-delay 2 --retry-connrefused -X PUT \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
--data "$(jq -n \
--arg content "${VERSION_CONTENT}" \
--arg sha "${VERSION_SHA}" \
--arg message "${TITLE}" \
--arg branch "next-release" \ --arg branch "next-release" \
'{content: $content, sha: $sha, message: $message, branch: $branch}')" \ --arg new_branch "next-release" \
"${API_URL}/contents/.version" '{content: $content, message: $message, branch: $branch, new_branch: $new_branch}')" \
else "${API_URL}/contents/CHANGELOG.md"
echo "Creating .version on next-release branch..."
curl -sf --retry 3 --retry-delay 2 --retry-connrefused -X POST \ echo "Adding .version to next-release branch..."
curl -sf -X POST \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--data "$(jq -n \ --data "$(jq -n \
@@ -188,99 +222,110 @@ jobs:
"${API_URL}/contents/.version" "${API_URL}/contents/.version"
fi fi
echo "Creating new PR..." if [ -n "${PR_INDEX}" ]; then
echo "Waiting for next-release branch to be ready..." echo "Updating existing PR #${PR_INDEX}..."
for i in $(seq 1 10); do curl -sf -X PATCH \
BRANCH_STATUS=$(curl -s --retry 3 --retry-delay 2 --retry-connrefused \
-w "%{http_code}" -o /dev/null \
-H "Authorization: token ${TOKEN}" \
"${API_URL}/branches/next-release")
if [ "${BRANCH_STATUS}" = "200" ]; then
echo "Branch ready after ${i} attempt(s)"
break
fi
if [ "${i}" = "10" ]; then
echo "Branch next-release not found after 10 attempts, giving up"
exit 1
fi
echo "Branch not ready yet (attempt ${i}/10), waiting..."
sleep 3
done
PR_DATA=$(jq -n \
--arg title "${TITLE}" \
--arg body "${DESCRIPTION}" \
--arg head "next-release" \
--arg base "${BASE_BRANCH}" \
'{title: $title, body: $body, head: $head, base: $base}')
for i in $(seq 1 5); do
RESPONSE=$(curl -s --retry 3 --retry-delay 2 --retry-connrefused \
-w "\n%{http_code}" -X POST \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--data "${PR_DATA}" \ --data "$(jq -n \
"${API_URL}/pulls") --arg title "${TITLE}" \
HTTP_CODE=$(echo "${RESPONSE}" | tail -1) --arg body "${DESCRIPTION}" \
BODY=$(echo "${RESPONSE}" | sed '$d') '{title: $title, body: $body}')" \
if [ "${HTTP_CODE}" -lt 400 ]; then "${API_URL}/pulls/${PR_INDEX}"
echo "PR created successfully" else
break echo "Creating new PR..."
fi curl -sf -X POST \
if [ "${i}" = "5" ]; then -H "Authorization: token ${TOKEN}" \
echo "Error creating PR after 5 attempts (HTTP ${HTTP_CODE}): ${BODY}" -H "Content-Type: application/json" \
exit 1 --data "$(jq -n \
fi --arg title "${TITLE}" \
echo "PR creation attempt ${i}/5 failed (HTTP ${HTTP_CODE}), retrying..." --arg body "${DESCRIPTION}" \
sleep 3 --arg head "next-release" \
done --arg base "${DEFAULT_BRANCH}" \
'{title: $title, body: $body, head: $head, base: $base}')" \
"${API_URL}/pulls"
fi
create-release: prepare-release:
name: Create Release name: Prepare Release
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: preconditions needs: preconditions
if: | if: |
github.ref_type == 'branch' && (github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch) ||
github.ref_name == github.event.repository.default_branch && github.ref_type == 'tag'
inputs.tag_only != true container:
image: orhunp/git-cliff:2.10.1@sha256:6ba0d1fcb051bd7b154cfb19c4b2b3bfa2c22c475f5285fc30606777b6573119
outputs:
version: ${{ steps.version.outputs.version }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install git-cliff
run: |
curl -sSfL "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-gnu.tar.gz" | tar xz
sudo mv "git-cliff-${GIT_CLIFF_VERSION}/git-cliff" /usr/local/bin/
git-cliff --version
- name: Generate changelog - name: Generate changelog
run: git-cliff --bump --unreleased --strip header > CHANGES.md run: |
if [ "${{ github.ref_type }}" = "tag" ]; then
git-cliff --bump --latest --strip header > CHANGES.md
else
git-cliff --bump --unreleased --strip header > CHANGES.md
fi
- name: Get version - name: Get version
id: version id: version
run: | run: |
VERSION=$(git-cliff --bumped-version 2>/dev/null || echo "") VERSION=$(git-cliff --bumped-version 2>/dev/null || echo "")
echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "${VERSION}" > VERSION
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: release-artifacts
path: |
CHANGES.md
VERSION
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: prepare-release
if: |
github.ref_type == 'branch' &&
github.ref_name == github.event.repository.default_branch &&
inputs.tag_only != true
container:
image: amd64/alpine:3.22.2@sha256:b687e78c6e2785808446f45b52f1540a1e58adc07bdcffea354933b18c613d90
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
run: apk add --no-cache git jq curl
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: release-artifacts
- name: Create release - name: Create release
env: env:
TOKEN: ${{ secrets.UNBOUND_RELEASE_TOKEN }}
REPOSITORY: ${{ github.repository }} REPOSITORY: ${{ github.repository }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
VERSION: ${{ steps.version.outputs.version }}
run: | run: |
TOKEN=$(cat "${RELEASE_TOKEN_FILE}")
if [ ! -r .version ]; then if [ ! -r .version ]; then
echo "Version file not found" echo "Version file not found"
exit 0 exit 0
fi fi
CURRENT_VERSION=$(cat .version 2>/dev/null | jq -r '.version') VERSION=$(cat .version 2>/dev/null | jq -r '.version')
LATEST=$(git describe --abbrev=0 --tags 2>/dev/null || echo '') LATEST=$(git describe --abbrev=0 --tags 2>/dev/null || echo '')
if [ -n "${LATEST}" ] && [ "${CURRENT_VERSION}" = "${LATEST}" ]; then if [ -n "${LATEST}" ] && [ "${VERSION}" = "${LATEST}" ]; then
echo "Version ${CURRENT_VERSION} already exists" echo "Version ${VERSION} already exists"
exit 0 exit 0
fi fi
@@ -288,15 +333,17 @@ jobs:
REPO=$(echo "${REPOSITORY}" | cut -d'/' -f2) REPO=$(echo "${REPOSITORY}" | cut -d'/' -f2)
API_URL="${GITEA_URL}/api/v1/repos/${OWNER}/${REPO}" API_URL="${GITEA_URL}/api/v1/repos/${OWNER}/${REPO}"
MESSAGE=$(cat CHANGES.md) NAME=$(cat VERSION)
MESSAGE=$(cat CHANGES.md | jq -Rs .)
MESSAGE="${MESSAGE:1:-1}" # Remove surrounding quotes
echo "Creating release ${VERSION}..." echo "Creating release ${NAME}..."
curl -sf --retry 3 --retry-delay 2 --retry-connrefused -X POST \ curl -sf -X POST \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--data "$(jq -n \ --data "$(jq -n \
--arg tag_name "${VERSION}" \ --arg tag_name "${NAME}" \
--arg name "${VERSION}" \ --arg name "${NAME}" \
--arg body "${MESSAGE}" \ --arg body "${MESSAGE}" \
--arg target "${DEFAULT_BRANCH}" \ --arg target "${DEFAULT_BRANCH}" \
'{tag_name: $tag_name, name: $name, body: $body, target_commitish: $target}')" \ '{tag_name: $tag_name, name: $name, body: $body, target_commitish: $target}')" \
@@ -305,46 +352,43 @@ jobs:
create-tag: create-tag:
name: Create Tag name: Create Tag
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: preconditions needs: prepare-release
if: | if: |
github.ref_type == 'branch' && github.ref_type == 'branch' &&
github.ref_name == github.event.repository.default_branch && github.ref_name == github.event.repository.default_branch &&
inputs.tag_only == true inputs.tag_only == true
container:
image: amd64/alpine:3.22.2@sha256:b687e78c6e2785808446f45b52f1540a1e58adc07bdcffea354933b18c613d90
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install git-cliff - name: Install dependencies
run: | run: apk add --no-cache git jq curl
curl -sSfL "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-gnu.tar.gz" | tar xz
sudo mv "git-cliff-${GIT_CLIFF_VERSION}/git-cliff" /usr/local/bin/
git-cliff --version
- name: Get version - name: Download artifacts
id: version uses: actions/download-artifact@v4
run: | with:
VERSION=$(git-cliff --bumped-version 2>/dev/null || echo "") name: release-artifacts
echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Create tag - name: Create tag
env: env:
TOKEN: ${{ secrets.UNBOUND_RELEASE_TOKEN }}
REPOSITORY: ${{ github.repository }} REPOSITORY: ${{ github.repository }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
VERSION: ${{ steps.version.outputs.version }}
run: | run: |
TOKEN=$(cat "${RELEASE_TOKEN_FILE}")
if [ ! -r .version ]; then if [ ! -r .version ]; then
echo "Version file not found" echo "Version file not found"
exit 0 exit 0
fi fi
CURRENT_VERSION=$(cat .version 2>/dev/null | jq -r '.version') VERSION=$(cat .version 2>/dev/null | jq -r '.version')
LATEST=$(git describe --abbrev=0 --tags 2>/dev/null || echo '') LATEST=$(git describe --abbrev=0 --tags 2>/dev/null || echo '')
if [ -n "${LATEST}" ] && [ "${CURRENT_VERSION}" = "${LATEST}" ]; then if [ -n "${LATEST}" ] && [ "${VERSION}" = "${LATEST}" ]; then
echo "Version ${CURRENT_VERSION} already exists" echo "Version ${VERSION} already exists"
exit 0 exit 0
fi fi
@@ -352,13 +396,15 @@ jobs:
REPO=$(echo "${REPOSITORY}" | cut -d'/' -f2) REPO=$(echo "${REPOSITORY}" | cut -d'/' -f2)
API_URL="${GITEA_URL}/api/v1/repos/${OWNER}/${REPO}" API_URL="${GITEA_URL}/api/v1/repos/${OWNER}/${REPO}"
echo "Creating tag ${VERSION}..." NAME=$(cat VERSION)
curl -sf --retry 3 --retry-delay 2 --retry-connrefused -X POST \
echo "Creating tag ${NAME}..."
curl -sf -X POST \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--data "$(jq -n \ --data "$(jq -n \
--arg tag_name "${VERSION}" \ --arg tag_name "${NAME}" \
--arg target "${DEFAULT_BRANCH}" \ --arg target "${DEFAULT_BRANCH}" \
--arg message "${VERSION}" \ --arg message "${NAME}" \
'{tag_name: $tag_name, target: $target, message: $message}')" \ '{tag_name: $tag_name, target: $target, message: $message}')" \
"${API_URL}/tags" "${API_URL}/tags"
-32
View File
@@ -1,32 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository Overview
This repository contains reusable Gitea Actions workflows for Unbound Software repositories. These workflows are called from other repositories using Gitea's `workflow_call` trigger.
## Architecture
- **Location**: Workflows are stored in `.gitea/workflows/` (not `.github/workflows/`)
- **Platform**: Gitea Actions (compatible with GitHub Actions syntax but runs on Gitea)
- **Runner**: Uses `ubuntu-latest` runner directly (no containers)
- **git-cliff**: Downloaded as binary from GitHub releases, version controlled via `GIT_CLIFF_VERSION` env var
### Release.yml Workflow
The main workflow automates semantic versioning releases using git-cliff for changelog generation:
1. **preconditions**: Validates release token exists at `/runner-secrets/release-token`
2. **changelog**: Generates changelog, determines version bump, checks for changes
3. **handle-pr**: Creates/updates a `next-release` branch and PR with CHANGELOG.md and .version
4. **prepare-release**: Prepares release artifacts when triggered
5. **create-release** or **create-tag**: Creates Gitea release or tag based on `tag_only` input
Version tracking uses a `.version` JSON file containing `{"version":"vX.Y.Z"}`.
## Development Notes
- No build/test commands exist - this is a workflow-only repository
- Workflows use Gitea API directly via curl (not gh CLI)
- Authentication reads from file-based token at `/runner-secrets/release-token`
+5 -3
View File
@@ -20,19 +20,21 @@ on:
jobs: jobs:
release: release:
uses: unboundsoftware/shared-workflows/.gitea/workflows/Release.yml@main uses: unboundsoftware/shared-workflows/.gitea/workflows/Release.yml@main
secrets:
UNBOUND_RELEASE_TOKEN: ${{ secrets.GIT_API_TOKEN }}
``` ```
**Inputs:** **Inputs:**
- `tag_only` (boolean, default: `false`): Set to `true` to only create tags without full releases - `tag_only` (boolean, default: `false`): Set to `true` to only create tags without full releases
**Requirements:** **Secrets:**
This workflow reads the release token from `/runner-secrets/release-token`, which is automatically available on Unbound's Gitea runners. No repository secrets need to be configured. - `UNBOUND_RELEASE_TOKEN` (required): Token with API access to create PRs and releases. Required scopes: `repository` (read/write), `issue` (read/write)
**How it works:** **How it works:**
1. On each push to the default branch, generates a changelog using git-cliff 1. On each push to the default branch, generates a changelog using git-cliff
2. Creates or updates a `next-release` branch with the updated CHANGELOG.md and .version file 2. Creates or updates a `next-release` branch with the updated CHANGELOG.md and .version file
3. Opens or updates a PR titled "chore(release): prepare for vX.Y.Z" 3. Opens or updates a PR titled "chore(release): prepare for vX.Y.Z"
4. When the .version file exists (after merging the release PR), creates a Gitea release with the changelog 4. When the .version file exists (after merging the release PR), creates a GitHub release with the changelog
-11
View File
@@ -2,16 +2,5 @@
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends": [
"config:recommended" "config:recommended"
],
"customManagers": [
{
"customType": "regex",
"fileMatch": ["^\\.gitea/workflows/.*\\.ya?ml$"],
"matchStrings": [
"GIT_CLIFF_VERSION:\\s*[\"']?(?<currentValue>[^\"'\\s]+)[\"']?"
],
"depNameTemplate": "orhun/git-cliff",
"datasourceTemplate": "github-releases"
}
] ]
} }