From f579b01e6b40d4a38fc087dcf66cc377358c4a40 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:30:27 +0000 Subject: [PATCH] chore(sync): synced file(s) with cplieger/ci --- .github/workflows/ci.yaml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/release.yaml | 17 +++- .github/workflows/security.yml | 2 +- .golangci.yaml | 7 +- cliff.toml | 163 ++++++++++++++++----------------- 6 files changed, 101 insertions(+), 92 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 23835e9..18999ff 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -35,4 +35,4 @@ concurrency: jobs: ci: - uses: cplieger/ci/.github/workflows/ci.yaml@c9c218d713f221dabb8504141b1ab4501d5ba7af # v2 + uses: cplieger/ci/.github/workflows/ci.yaml@3ec077ed6f632b1a1276ed92269c0fb391c753aa # v3 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4371c06..b6ec3bf 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -25,4 +25,4 @@ jobs: security-events: write contents: read actions: read - uses: cplieger/ci/.github/workflows/codeql.yaml@c9c218d713f221dabb8504141b1ab4501d5ba7af # v2 + uses: cplieger/ci/.github/workflows/codeql.yaml@3ec077ed6f632b1a1276ed92269c0fb391c753aa # v3 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9b36022..35fcc69 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -3,14 +3,13 @@ # cplieger/ci/.github/workflows/release.yaml; this file only calls it. The # central pipeline selects the channel from the branch it runs on (main is the # stable channel), computes the version, detects the repo type and the changed -# paths, and publishes. This file triggers on main only until the pinned -# pipeline is one that publishes a dev channel from a dev push. Per-repo +# paths, and publishes; a push to dev publishes the dev channel. Per-repo # behaviour is the "Resolve repo policy" step there; no override surface here. name: Release on: push: - branches: [main] + branches: [main, dev] workflow_dispatch: inputs: # Read by the v2 pipeline's no-change gate through github.event.inputs @@ -20,6 +19,14 @@ on: description: "Skip publishing when the rebuilt image is package-identical to :latest (used by the scheduled staleness rebuild)." type: boolean default: false + # Read by the two-branch pipeline through github.event.inputs, never + # `with:`, which a v2 pin does not declare. A stable run's dev barrier + # dispatches `renumber` on dev; a person never needs to. + mode: + description: "'renumber' re-tags dev's newest builds under fresh pre-release versions; 'normal' otherwise." + type: choice + options: [normal, renumber] + default: normal # Serialize release runs per repo. Two merges seconds apart otherwise race: # the losing run can 403 even on the git-refs tag create and strand a @@ -44,13 +51,15 @@ permissions: jobs: release: permissions: + # The two-branch dev barrier dispatches dev release runs. + actions: write contents: write statuses: write packages: write id-token: write attestations: write security-events: write - uses: cplieger/ci/.github/workflows/release.yaml@c9c218d713f221dabb8504141b1ab4501d5ba7af # v2 + uses: cplieger/ci/.github/workflows/release.yaml@3ec077ed6f632b1a1276ed92269c0fb391c753aa # v3 # Forward only the two Docker Hub publish credentials the reusable pipeline # actually declares and consumes, rather than `secrets: inherit` (which # exposes every repo secret to the reusable-workflow trust boundary). Both diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 483efa9..7689370 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -28,4 +28,4 @@ jobs: permissions: contents: read security-events: write - uses: cplieger/ci/.github/workflows/security-scan.yaml@c9c218d713f221dabb8504141b1ab4501d5ba7af # v2 + uses: cplieger/ci/.github/workflows/security-scan.yaml@3ec077ed6f632b1a1276ed92269c0fb391c753aa # v3 diff --git a/.golangci.yaml b/.golangci.yaml index f004145..7b8d56b 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -8,6 +8,12 @@ run: linters: default: standard + # unused, ineffassign and wastedassign are off: go-ci's deadset step reports + # the same findings (DS1002, DS1003, DS1807) and gates on them in every Go + # module. + disable: + - unused + - ineffassign enable: - bodyclose - noctx @@ -21,7 +27,6 @@ linters: - unconvert - unparam - prealloc - - wastedassign - intrange - modernize - usestdlibvars diff --git a/cliff.toml b/cliff.toml index ab0b868..da041eb 100644 --- a/cliff.toml +++ b/cliff.toml @@ -9,57 +9,21 @@ initial_tag = "v1.0.0" [changelog] header = "" -# Migration steps lead, then the ordinary grouped log. -# -# Conventional-commit parsing strips the type AND the `!` from commit.message, so -# a `feat!:` renders under "### Added" with nothing marking it breaking -- hence -# the [**breaking**] marker in the group list, which is the INDEX of breaking -# changes. The BREAKING CHANGE footer is where the migration steps live and was -# discarded entirely -- hence the leading section, which is only the INSTRUCTIONS. -# -# Only the FOOTER is surfaced, never the commit body: a footer is written as an -# instruction to the reader ("rename X to Y before upgrading"), while the body is -# rationale that belongs in git log. Rendering bodies too was measured at ~105 KB -# for one repo's release against ~13 KB for this shape. -# -# Three mechanics, all load-bearing rather than stylistic, and all paid for by -# plex-language-sync v2.0.0 -- the first release this template rendered with three -# breaking commits and one footer between them (2026-08-21). -# -# 1. A footer-bearing commit gets its own `####` subheading. The first shape put -# every breaking SUBJECT in a flat bullet list and then one quote block under -# it, so with three breaking commits and one footer the reader could not tell -# which subject the migration steps belonged to, and each subject was printed -# twice (3 bullets here + 3 marked lines in the groups = 6 lines for 3 -# changes). Only footer-bearing commits appear here now; a breaking commit -# with no footer is named once, by its marker in the group list. -# -# 2. The footer is emitted as ORDINARY MARKDOWN, never quoted with `> `. A -# blockquote silently destroys pre-formatted content: measured through -# GitHub's own /markdown endpoint, an aligned env-var table inside `> ` comes -# back as `
` and the browser collapses its space runs, while the same text -# unquoted comes back as `
` with the alignment intact. Worse, markdown's
-# 4-space code-block threshold applies AFTER the `> ` is stripped, so the
-# author's indent depth decided whether a table survived (2 spaces became
-# mush, 6 spaces became a code block) with nothing telling them which they
-# picked. Unquoted, a fenced block in the commit footer reaches the reader as
-# a fenced block.
-#
-# 3. `set_global` is required, and an attribute filter cannot replace it.
-# breaking_description falls back to the SUBJECT when a commit has no
-# BREAKING CHANGE footer, so `filter(attribute="breaking_description")` keeps
-# EVERY breaking commit (verified: 2 of 2 footerless commits kept) and a
-# release whose breaking commits all lack footers rendered a bare
-# "### Breaking changes" heading with nothing beneath it. The flag emits the
-# heading lazily, on the first commit whose description differs from its
-# subject, so the section is absent when it would be empty. Verified both
-# ways on the pinned git-cliff v2.13.1: a mixed set yields the heading plus
-# one entry, an all-footerless set yields no heading at all.
+# A breaking commit renders once: with a BREAKING CHANGE footer as a `####`
+# subheading under "Breaking changes", footer unquoted (a `> ` quote collapses
+# tables and code blocks), else marked in its group. breaking_description
+# falls back to the subject, so "has a footer" is description != message.
+# CLIFF_NOTES_MODE=v3, set only by cplieger/ci's render-notes.sh, hides
+# deps/devdeps scopes and orders Security, Added, Fixed, Performance, Changed.
+# Tera rejects `in` inside a parenthesised condition, hence the `set` flags.
+# Only the footer renders, never the body, which is rationale for git log.
body = """
-{% set brk = commits | filter(attribute="breaking", value=true) %}\
+{% set v3 = get_env(name="CLIFF_NOTES_MODE", default="") == "v3" %}\
{% set_global shown = false %}\
-{% for commit in brk %}\
-{% if commit.breaking_description and commit.breaking_description | trim != commit.message | trim %}\
+{% for commit in commits %}\
+{% set footer = commit.breaking and commit.breaking_description and commit.breaking_description | trim != commit.message | trim %}\
+{% set hidden = v3 and commit.scope in ["deps", "devdeps"] %}\
+{% if footer and not hidden %}\
{% if not shown %}
### Breaking changes
{% set_global shown = true %}\
@@ -69,12 +33,52 @@ body = """
{{ commit.breaking_description | trim | upper_first }}
{% endif %}\
{% endfor %}\
-{% for group, commits in commits | group_by(attribute="group") %}
-### {{ group | striptags | trim | upper_first }}
-{% for commit in commits %}
+{% if v3 %}\
+{% set_global sections = ["Security", "Added", "Fixed", "Performance", "Changed"] %}\
+{% for group, gcommits in commits | group_by(attribute="group") %}\
+{% set label = group | striptags | trim %}\
+{% if label not in sections %}\
+{% set_global sections = sections | concat(with=label) %}\
+{% endif %}\
+{% endfor %}\
+{% for section in sections %}\
+{% set_global keep = [] %}\
+{% for commit in commits %}\
+{% set label = commit.group | striptags | trim %}\
+{% set perf = commit.raw_message is starting_with("perf") %}\
+{% if section == "Performance" %}{% set wanted = label == "Changed" and perf %}\
+{% elif section == "Changed" %}{% set wanted = label == "Changed" and not perf %}\
+{% else %}{% set wanted = label == section %}{% endif %}\
+{% set footer = commit.breaking and commit.breaking_description and commit.breaking_description | trim != commit.message | trim %}\
+{% set hidden = commit.scope in ["deps", "devdeps"] %}\
+{% if wanted and not hidden and not footer %}\
+{% set_global keep = keep | concat(with=commit) %}\
+{% endif %}\
+{% endfor %}\
+{% if keep | length > 0 %}
+### {{ section | upper_first }}
+{% for commit in keep %}
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
{% endfor %}
+{% endif %}\
+{% endfor %}\
+{% else %}\
+{% for group, gcommits in commits | group_by(attribute="group") %}\
+{% set_global keep = [] %}\
+{% for commit in gcommits %}\
+{% set footer = commit.breaking and commit.breaking_description and commit.breaking_description | trim != commit.message | trim %}\
+{% if not footer %}\
+{% set_global keep = keep | concat(with=commit) %}\
+{% endif %}\
+{% endfor %}\
+{% if keep | length > 0 %}
+### {{ group | striptags | trim | upper_first }}
+{% for commit in keep %}
+- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
{% endfor %}
+{% endif %}\
+{% endfor %}\
+{% endif %}
"""
trim = true
@@ -92,23 +96,23 @@ protect_breaking_commits = false
# scripts/test-cliff-bump-semantics.sh pin both hazards.
tag_pattern = '^v[0-9]+\.[0-9]+\.[0-9]+$'
-# Path-level noise filter: a commit whose changed files ALL match these globs
-# never appears in the changelog and never drives a version bump (exclusions
-# feed --bumped-version, so the release boolean agrees). A commit touching
-# both an excluded and a shipped path is still included. Bare patterns are
-# root-anchored; `**/` matches at any depth (git-cliff v2.13.1, verified).
-#
-# This list mirrors the build gate (EXCLUDE_PATTERNS in the central
-# release.yaml detect job) so "builds" and "releases" agree on significance.
-# Keep it a strict SUBSET of that list: never exclude here a path the build
-# gate treats as significant. Inclusion criterion: only paths that commits
-# with non-skipped types (feat/fix/sec/chore(deps)) realistically touch
-# exclusively — everything else (lint configs, .editorconfig, ...) arrives
-# via skip-typed commits (chore(sync):, lint:, ci:) and is filtered by type.
+# A commit whose changed files ALL match these globs is left out of the notes
+# and the version bump; one that also touches a shipped path still counts.
+# Bare patterns are root-anchored, `**/` matches at any depth. Invariant: a
+# strict subset of EXCLUDE_PATTERNS in cplieger/ci's
+# scripts/path-significance.sh, holding only paths a releasing-type commit
+# can touch alone.
exclude_paths = [
".github/", # CI workflows + pins: never in the artifact
"**/*.md", # docs, incl. fix:-typed README-only edits
"LICENSE",
+ # README images, the subset of path-significance.sh's root docs/ image pattern.
+ "docs/**/*.png",
+ "docs/**/*.jpg",
+ "docs/**/*.jpeg",
+ "docs/**/*.webp",
+ "docs/**/*.gif",
+ "docs/**/*.svg",
"alerts/", # README-companion alert rules, one file per
# expression language (a ruler parses every expr in
# the file it loads, and PromQL/LogQL are mutually
@@ -127,26 +131,14 @@ exclude_paths = [
".gitignore",
".gitattributes",
".editorconfig",
- # punused adjudications: the repo-owned whitelist the go-ci unused-export gate
- # reads. Dev-only, never in an artifact, and an adjudication-only commit ships
- # nothing — but it is the one dotfile here a `refactor:`-typed commit plausibly
- # touches alone (deleting dead code and recording the survivors is one change;
- # recording them alone is the follow-up), and `refactor:` is a RELEASING type.
- # `**/` not bare: go-ci reads this file relative to its working-directory, so a
- # nested Go module's copy lives at /.punused-ignore and the root-anchored
- # form would miss it (measured on the pinned cliff v2.13.1 — bare excludes the
- # root file only, `**/` excludes both, and a real code commit still bumps).
+ # deadset's configuration, adjudications and cross-language edges, which a
+ # `refactor:` commit can touch alone. `**/`: each sits at its target root,
+ # which in a hybrid repo or a nested Go module is a subdirectory.
+ "**/deadset.json",
+ "**/deadset-ignore.json",
+ "**/deadset-edges.json",
+ # knip's configs, and the retired .punused-ignore repos carry until they delete it.
"**/.punused-ignore",
- # knip suppressions and enrolment: the TS twin of .punused-ignore, read by
- # ts-ci's unused-deps/exports gate. Dev-only, never in an artifact, and a
- # suppression-only commit ships nothing — but `refactor:` is a RELEASING type,
- # so a config-only commit was minting a version and a changelog line.
- # release.yaml's EXCLUDE_PATTERNS already dropped it from the BUILD gate; this
- # is the RELEASE gate catching up. All eight forms knip itself loads
- # (KNIP_CONFIG_LOCATIONS in knip/dist/constants.js), since only knip.json is
- # in use today and the others must not reopen the gap. `**/` not bare: every
- # enrolled config lives beside its package.json, which in a hybrid repo is a
- # subdirectory (static-src/, web/, internal/server/static-src/).
"**/knip.json",
"**/knip.jsonc",
"**/.knip.json",
@@ -170,6 +162,9 @@ commit_parsers = [
# versions) share this commit type but are dropped by exclude_paths above
# (.github/) before parsing ever sees them.
{ message = "^chore\\(deps\\)", group = "Dependencies" },
+ # Renovate types runtime dependency updates `fix(deps)`; they are
+ # dependency bumps, not fixes.
+ { message = "^fix\\(deps\\)", group = "Dependencies" },
# Pure-meta commits never warrant a release. `no_increment_regex` is
# documented to skip these but doesn't actually prevent the patch fallback
# (cliff v2.13.1; upstream issue #1570, fixed on main after v2.13.1) —