From 0ae27adf90eb6c656e35402e5634cad692afe873 Mon Sep 17 00:00:00 2001 From: Julian Lechner Date: Fri, 2 Oct 2026 15:08:22 +0200 Subject: [PATCH] ci: share Gitea CD publish action --- .gitea/actions/publish/action.yml | 132 ++++++++++++++++++++++++++++ .gitea/workflows/CD Development.yml | 112 ++--------------------- .gitea/workflows/CD Production.yml | 113 ++---------------------- 3 files changed, 149 insertions(+), 208 deletions(-) create mode 100644 .gitea/actions/publish/action.yml diff --git a/.gitea/actions/publish/action.yml b/.gitea/actions/publish/action.yml new file mode 100644 index 0000000..13ed45e --- /dev/null +++ b/.gitea/actions/publish/action.yml @@ -0,0 +1,132 @@ +name: Publish portfolio +description: Build the image and create the matching Gitea release + +inputs: + image-tag: + description: Docker image tag + required: true + prerelease: + description: Whether the Gitea release is a pre-release + required: true + registry-username: + description: Registry username + required: true + registry-password: + description: Registry password or token + required: true + gitea-token: + description: Token for Gitea releases + required: true + +runs: + using: composite + steps: + - name: Use Node.js v24.15.0 + uses: actions/setup-node@v4 + with: + node-version: '24.15.0' + + - name: Set build version + shell: bash + run: npm run version:set + + - name: Read version from package.json + id: version + shell: bash + env: + PRERELEASE: ${{ inputs.prerelease }} + run: | + version=$(node -p 'require("./package.json").version') + release_tag="v${version//+/-}" + if [ "$PRERELEASE" = true ]; then + release_tag="${release_tag}-dev" + fi + echo "value=$version" >> "$GITHUB_OUTPUT" + echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT" + echo "revision=$GITEA_RUN_ATTEMPT" >> "$GITHUB_OUTPUT" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to registry + uses: docker/login-action@v3 + with: + registry: docker.lechner-systems.at + username: ${{ inputs.registry-username }} + password: ${{ inputs.registry-password }} + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + context: . + push: true + provenance: false + build-args: | + APP_VERSION=${{ steps.version.outputs.value }} + VCS_REF=${{ steps.version.outputs.revision }} + tags: docker.lechner-systems.at/lechnersystems/portfolio:${{ inputs.image-tag }} + + - name: Create Gitea release + shell: bash + env: + GITEA_TOKEN: ${{ inputs.gitea-token }} + RELEASE_TAG: ${{ steps.version.outputs.release_tag }} + PRERELEASE: ${{ inputs.prerelease }} + run: | + api_url="${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases" + # ponytail: 50 recent releases cover normal reruns; paginate if old releases are rebuilt. + releases="$(curl --fail-with-body --silent --show-error \ + --header "Authorization: token ${GITEA_TOKEN}" \ + "${api_url}?limit=50")" + previous_tag="$(printf '%s' "$releases" | jq -r \ + --arg tag "$RELEASE_TAG" \ + --argjson prerelease "$PRERELEASE" \ + '[.[] | select(.draft == false and .prerelease == $prerelease and .tag_name != $tag)][0].tag_name // empty')" + + if [ -n "$previous_tag" ]; then + commit_messages="$(git log --reverse --format='- %s' "${previous_tag}..${GITEA_SHA}")" + full_changelog="${{ gitea.server_url }}/${{ gitea.repository }}/compare/${previous_tag}...${RELEASE_TAG}" + else + commit_messages="$(git log --reverse --format='- %s' "${GITEA_SHA}")" + full_changelog="" + fi + + if [ -z "$commit_messages" ]; then + commit_messages='- No commits since the previous release' + fi + + { + echo '## Changes' + echo + printf '%s\n' "$commit_messages" + echo + if [ -n "$full_changelog" ]; then + echo "**Full Changelog**: ${full_changelog}" + fi + } > release-notes.md + + jq --null-input \ + --arg tag "$RELEASE_TAG" \ + --arg target "$GITEA_SHA" \ + --argjson prerelease "$PRERELEASE" \ + --rawfile body release-notes.md \ + '{tag_name: $tag, target_commitish: $target, name: $tag, body: $body, prerelease: $prerelease}' \ + > release.json + + release_id="$(printf '%s' "$releases" | jq -r \ + --arg tag "$RELEASE_TAG" \ + '.[] | select(.tag_name == $tag) | .id')" + if [ -n "$release_id" ]; then + method=PATCH + release_url="${api_url}/${release_id}" + else + method=POST + release_url="$api_url" + fi + + curl --fail-with-body --silent --show-error \ + --request "$method" \ + --header "Authorization: token ${GITEA_TOKEN}" \ + --header 'Content-Type: application/json' \ + --data-binary @release.json \ + "$release_url" diff --git a/.gitea/workflows/CD Development.yml b/.gitea/workflows/CD Development.yml index 51038ab..a746529 100644 --- a/.gitea/workflows/CD Development.yml +++ b/.gitea/workflows/CD Development.yml @@ -5,10 +5,6 @@ on: schedule: - cron: '0 23 * * *' -env: - REGISTRY: docker.lechner-systems.at - IMAGE_NAME: lechnersystems/portfolio - jobs: changes: runs-on: ubuntu-latest @@ -46,114 +42,24 @@ jobs: fi fi - docker: + publish: needs: changes if: needs.changes.outputs.changed == 'true' runs-on: ubuntu-latest permissions: code: read releases: write - steps: - name: Checkout repository uses: actions/checkout@v4 - - - name: Use Node.js v24.15.0 - uses: actions/setup-node@v4 with: - node-version: '24.15.0' + fetch-depth: 0 - - name: Set build version - run: npm run version:set - - - name: Read version from package.json - id: version - run: | - version=$(node -p 'require("./package.json").version') - docker_tag=${version//+/-} - revision=${GITEA_RUN_ATTEMPT} - echo "value=$version" >> "$GITHUB_OUTPUT" - echo "docker_tag=$docker_tag" >> "$GITHUB_OUTPUT" - echo "revision=$revision" >> "$GITHUB_OUTPUT" - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to registry - uses: docker/login-action@v3 + - name: Publish development image and pre-release + uses: ./.gitea/actions/publish with: - registry: ${{ env.REGISTRY }} - username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} - password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }} - - - name: Build and push development image - uses: docker/build-push-action@v6 - with: - context: . - push: true - provenance: false - build-args: | - APP_VERSION=${{ steps.version.outputs.value }} - VCS_REF=${{ steps.version.outputs.revision }} - tags: | - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev - - - name: Create Gitea pre-release - env: - GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - RELEASE_TAG: v${{ steps.version.outputs.docker_tag }} - run: | - api_url="${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases" - releases="$(curl --fail-with-body --silent --show-error \ - --header "Authorization: token ${GITEA_TOKEN}" \ - "${api_url}?limit=50")" - previous_tag="$(printf '%s' "$releases" | jq -r \ - --arg tag "$RELEASE_TAG" \ - '[.[] | select(.draft == false and .prerelease == true and .tag_name != $tag)][0].tag_name // empty')" - - if [ -n "$previous_tag" ]; then - commit_messages="$(git log --reverse --format='- %s' "${previous_tag}..${GITEA_SHA}")" - full_changelog="${{ gitea.server_url }}/${{ gitea.repository }}/compare/${previous_tag}...${RELEASE_TAG}" - else - commit_messages="$(git log --reverse --format='- %s' "${GITEA_SHA}")" - full_changelog="" - fi - - if [ -z "$commit_messages" ]; then - commit_messages='- No commits since the previous pre-release' - fi - - { - echo '## Changes' - echo - printf '%s\n' "$commit_messages" - echo - if [ -n "$full_changelog" ]; then - echo "**Full Changelog**: ${full_changelog}" - fi - } > release-notes.md - - jq --null-input \ - --arg tag "$RELEASE_TAG" \ - --arg target "$GITEA_SHA" \ - --rawfile body release-notes.md \ - '{tag_name: $tag, target_commitish: $target, name: $tag, body: $body, prerelease: true}' \ - > release.json - - release_id="$(printf '%s' "$releases" | jq -r \ - --arg tag "$RELEASE_TAG" \ - '.[] | select(.tag_name == $tag) | .id')" - if [ -n "$release_id" ]; then - method=PATCH - release_url="${api_url}/${release_id}" - else - method=POST - release_url="$api_url" - fi - - curl --fail-with-body --silent --show-error \ - --request "$method" \ - --header "Authorization: token ${GITEA_TOKEN}" \ - --header 'Content-Type: application/json' \ - --data-binary @release.json \ - "$release_url" + image-tag: dev + prerelease: 'true' + registry-username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} + registry-password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }} + gitea-token: ${{ secrets.GITEA_TOKEN }} diff --git a/.gitea/workflows/CD Production.yml b/.gitea/workflows/CD Production.yml index c8fad62..777547e 100644 --- a/.gitea/workflows/CD Production.yml +++ b/.gitea/workflows/CD Production.yml @@ -3,120 +3,23 @@ name: CD Production on: workflow_dispatch: -env: - REGISTRY: docker.lechner-systems.at - IMAGE_NAME: lechnersystems/portfolio - jobs: - docker: + publish: runs-on: ubuntu-latest permissions: code: read releases: write - steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Use Node.js v24.15.0 - uses: actions/setup-node@v4 + - name: Publish latest image and stable release + uses: ./.gitea/actions/publish with: - node-version: '24.15.0' - - - name: Set build version - run: npm run version:set - - - name: Read version from package.json - id: version - run: | - version=$(node -p 'require("./package.json").version') - docker_tag=${version//+/-} - revision=${GITEA_RUN_ATTEMPT} - echo "value=$version" >> "$GITHUB_OUTPUT" - echo "docker_tag=$docker_tag" >> "$GITHUB_OUTPUT" - echo "revision=$revision" >> "$GITHUB_OUTPUT" - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} - password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }} - - - name: Build and push latest image - uses: docker/build-push-action@v6 - with: - context: . - push: true - provenance: false - build-args: | - APP_VERSION=${{ steps.version.outputs.value }} - VCS_REF=${{ steps.version.outputs.revision }} - tags: | - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - - name: Create Gitea release - env: - GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - RELEASE_TAG: v${{ steps.version.outputs.docker_tag }} - run: | - api_url="${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases" - # ponytail: 50 recent releases cover normal reruns; paginate if old releases are rebuilt. - releases="$(curl --fail-with-body --silent --show-error \ - --header "Authorization: token ${GITEA_TOKEN}" \ - "${api_url}?limit=50")" - previous_tag="$(printf '%s' "$releases" | jq -r \ - --arg tag "$RELEASE_TAG" \ - '[.[] | select(.draft == false and .prerelease == false and .tag_name != $tag)][0].tag_name // empty')" - - if [ -n "$previous_tag" ]; then - commit_messages="$(git log --reverse --format='- %s' "${previous_tag}..${GITEA_SHA}")" - full_changelog="${{ gitea.server_url }}/${{ gitea.repository }}/compare/${previous_tag}...${RELEASE_TAG}" - else - commit_messages="$(git log --reverse --format='- %s' "${GITEA_SHA}")" - full_changelog="" - fi - - if [ -z "$commit_messages" ]; then - commit_messages='- No commits since the previous release' - fi - - { - echo '## Changes' - echo - printf '%s\n' "$commit_messages" - echo - if [ -n "$full_changelog" ]; then - echo "**Full Changelog**: ${full_changelog}" - fi - } > release-notes.md - - jq --null-input \ - --arg tag "$RELEASE_TAG" \ - --arg target "$GITEA_SHA" \ - --rawfile body release-notes.md \ - '{tag_name: $tag, target_commitish: $target, name: $tag, body: $body, prerelease: false}' \ - > release.json - - release_id="$(printf '%s' "$releases" | jq -r \ - --arg tag "$RELEASE_TAG" \ - '.[] | select(.tag_name == $tag) | .id')" - if [ -n "$release_id" ]; then - method=PATCH - release_url="${api_url}/${release_id}" - else - method=POST - release_url="$api_url" - fi - - curl --fail-with-body --silent --show-error \ - --request "$method" \ - --header "Authorization: token ${GITEA_TOKEN}" \ - --header 'Content-Type: application/json' \ - --data-binary @release.json \ - "$release_url" + image-tag: latest + prerelease: 'false' + registry-username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} + registry-password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }} + gitea-token: ${{ secrets.GITEA_TOKEN }}