Files
dependabot[bot] add79a5321 Bump the github-actions group with 3 updates
Bumps the github-actions group with 3 updates: [actions/setup-python](https://github.com/actions/setup-python), [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) and [docker/login-action](https://github.com/docker/login-action).


Updates `actions/setup-python` from 7.0.0 to 7.1.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/5fda3b95a4ea91299a34e894583c3862153e4b97...6d4fd22b20465ccc0f7354476588e8df7c9ca0e0)

Updates `zizmorcore/zizmor-action` from 0.7.1 to 0.8.0
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](https://github.com/zizmorcore/zizmor-action/compare/85b2b9fb8e3325e7a23d7d0a9d7ba5ae0f999e3e...53290badfa369cb0bf7ad16342cb62c2fa47ac7b)

Updates `docker/login-action` from 4.6.0 to 4.7.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/dbcb813823bdd20940b903addbd779551569679f...81c6f93d4bc991e510b342a00b419b3bb4efc5c6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/login-action
  dependency-version: 4.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-30 15:05:45 +00:00

235 lines
9.3 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cuts a GitHub Release on each minor/major tag, with a changelog and the
# compiled templates.json attached
name: 🚀 Release
on:
push:
tags:
# Minor + major bumps only (patch tags end in a non-zero patch, e.g. v0.9.1)
- 'v[0-9]+.[0-9]+.0'
workflow_dispatch:
inputs:
tag:
description: 'Existing tag to (re)generate the release for, e.g. v0.10.0'
required: true
type: string
# Least privilege by default; the job elevates to contents:write to publish
permissions:
contents: read
# Never let two releases for the same tag run at once; don't cancel a publish
concurrency:
group: ${{ github.workflow }}-${{ github.event.inputs.tag || github.ref_name }}
cancel-in-progress: false
jobs:
release:
name: 🚀 Publish Release
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history + all tags: we diff templates.json between two tags
fetch-depth: 0
# We authenticate gh with an explicit token below
persist-credentials: false
- name: Set up Python 🐍
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: '3.x'
- name: Resolve tags
id: refs
env:
INPUT_TAG: ${{ github.event.inputs.tag }}
REF_NAME: ${{ github.ref_name }}
run: |
set -euo pipefail
# The tag being released: the dispatch input, else the pushed tag
target="${INPUT_TAG:-$REF_NAME}"
if ! [[ "$target" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::'${target}' is not a vMAJOR.MINOR.PATCH tag"
exit 1
fi
if ! git rev-parse -q --verify "refs/tags/${target}^{commit}" >/dev/null; then
echo "::error::Tag '${target}' does not exist"
exit 1
fi
# Previous release: highest minor/major tag reachable from this one
prev=$(git tag --sort=-v:refname --merged "${target}^{commit}" \
| grep -E '^v[0-9]+\.[0-9]+\.0$' \
| grep -Fvx -- "${target}" \
| awk 'NR==1' || true)
if [ -n "$prev" ]; then
echo "Releasing ${target}; previous release was ${prev}"
else
echo "Releasing ${target}; no previous release found (treating as first)"
fi
{
echo "target=${target}"
echo "prev=${prev}"
} >> "$GITHUB_OUTPUT"
- name: Build changelog + asset
id: notes
env:
TARGET: ${{ steps.refs.outputs.target }}
PREV: ${{ steps.refs.outputs.prev }}
REPO_URL: ${{ github.server_url }}/${{ github.repository }}
run: |
set -euo pipefail
# templates.json at the tag being released (hard requirement)
if ! git cat-file -e "${TARGET}:templates.json" 2>/dev/null; then
echo "::error::templates.json not found at ${TARGET}; nothing to release"
exit 1
fi
git show "${TARGET}:templates.json" > new.json
total=$(jq '.templates | length' new.json)
# Release title, e.g. "Portainer Templates v0.11.0 (June 2026)". Month comes
# from the tag's own creation date, so re-runs keep the original month.
month=$(TZ=UTC git for-each-ref \
--format='%(creatordate:format-local:%B %Y)' "refs/tags/${TARGET}")
[ -n "$month" ] || month=$(date -u '+%B %Y')
title="Portainer Templates ${TARGET} (${month})"
# Shares the changelog's diff, so a rename isn't a removal plus an addition
python3 lib/changelog.py --diff "$PREV" "$TARGET" > diff.json
added=$(jq '.added | length' diff.json)
removed=$(jq '.removed | length' diff.json)
renamed=$(jq '.renamed | length' diff.json)
updated=$(jq '.updated | length' diff.json)
# Render the release notes (lists capped inside jq)
jq -r -n \
--slurpfile d diff.json \
--arg prev "$PREV" \
--arg cur "$TARGET" \
--arg total "$total" \
--arg repo "$REPO_URL" \
--arg site "https://portainer-templates.as93.net" '
($d[0]) as $d |
# must match the website slugify in src/routes/[slug]/+page.server.ts
def slugify: ascii_downcase | gsub("[^a-z ]"; "") | gsub(" "; "-");
def md_esc: gsub("(?<x>[\\[\\]])"; "\\\(.x)");
def item(link): if link then "- [\(md_esc)](\($site)/\(. | slugify))" else "- \(.)" end;
def renamed_item: "- [\(.to | md_esc)](\($site)/\(.to | slugify)) (was \(.from | md_esc))";
def section(title; arr; cap; render):
if (arr | length) == 0 then empty
else
"### \(title) (\(arr | length))",
(arr[0:cap][] | render),
(if (arr | length) > cap
then "- …and \((arr | length) - cap) more"
else empty end),
""
end;
"\($cur) includes \($total) stacks and apps from upstream sources",
( if $prev == "" then empty
else
"",
section("➕ Added"; $d.added; 40; item(true)),
section("➖ Removed"; $d.removed; 40; item(false)),
section("🏷️ Renamed"; $d.renamed; 40; renamed_item),
section("🔄 Updated"; $d.updated; 40; item(true)),
"[Full diff](\($repo)/compare/\($prev)...\($cur))"
end )
' > notes.md
# The tag's templates.json becomes the release asset
cp new.json templates.json
echo "Changelog: +${added} added, -${removed} removed, ${renamed} renamed, ~${updated} updated (${total} total)"
# Skip publishing if nothing changed -- unless it's the first release
# (no previous), which is always worth cutting.
if [ -n "$PREV" ] && [ "$((added + removed + renamed + updated))" -eq 0 ]; then
changed=false
echo "::notice::No template changes since ${PREV}; skipping the release"
else
changed=true
fi
{
echo "total=${total}"
echo "added=${added}"
echo "removed=${removed}"
echo "renamed=${renamed}"
echo "updated=${updated}"
echo "changed=${changed}"
echo "title=${title}"
} >> "$GITHUB_OUTPUT"
- name: Publish release
id: publish
if: steps.notes.outputs.changed == 'true'
env:
TARGET: ${{ steps.refs.outputs.target }}
TITLE: ${{ steps.notes.outputs.title }}
GH_TOKEN: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail
# Idempotent: update an existing release, else create it
if gh release view "$TARGET" >/dev/null 2>&1; then
echo "Release ${TARGET} already exists, updating notes + asset"
gh release edit "$TARGET" --title "$TITLE" --notes-file notes.md
gh release upload "$TARGET" templates.json --clobber
echo "result=updated" >> "$GITHUB_OUTPUT"
else
echo "Creating release ${TARGET}"
gh release create "$TARGET" templates.json \
--title "$TITLE" \
--notes-file notes.md \
--verify-tag
echo "result=created" >> "$GITHUB_OUTPUT"
fi
- name: Summary
if: always()
env:
TARGET: ${{ steps.refs.outputs.target }}
PREV: ${{ steps.refs.outputs.prev }}
TITLE: ${{ steps.notes.outputs.title }}
TOTAL: ${{ steps.notes.outputs.total }}
ADDED: ${{ steps.notes.outputs.added }}
REMOVED: ${{ steps.notes.outputs.removed }}
RENAMED: ${{ steps.notes.outputs.renamed }}
UPDATED: ${{ steps.notes.outputs.updated }}
CHANGED: ${{ steps.notes.outputs.changed }}
RESULT: ${{ steps.publish.outputs.result }}
PUBLISH_OUTCOME: ${{ steps.publish.outcome }}
REPO_URL: ${{ github.server_url }}/${{ github.repository }}
run: |
set -euo pipefail
{
echo "## Release"
echo ""
echo "| Field | Value |"
echo "|-------|-------|"
if [ "${RESULT:-}" = "created" ] || [ "${RESULT:-}" = "updated" ]; then
echo "| Release | ✅ [${TITLE:-$TARGET}](${REPO_URL}/releases/tag/${TARGET}) (${RESULT}) |"
elif [ "${CHANGED:-}" = "false" ]; then
echo "| Release | ⏭️ Skipped — no template changes since \`${PREV:-none}\` |"
elif [ "${PUBLISH_OUTCOME:-}" = "failure" ]; then
echo "| Release | ❌ Failed for \`${TARGET:-n/a}\` |"
else
echo "| Release | ⏭️ Skipped |"
fi
echo "| Previous | \`${PREV:-none}\` |"
echo "| Templates | ${TOTAL:-n/a} total |"
echo "| Changes | ✨ ${ADDED:-0} added · 🗑️ ${REMOVED:-0} removed · 🏷️ ${RENAMED:-0} renamed · ♻️ ${UPDATED:-0} updated |"
} >> "$GITHUB_STEP_SUMMARY"