Skip to content

fix(release): default to moving latest tag; require typed phrase to skip#36311

Merged
sfreudenthaler merged 2 commits into
mainfrom
fix/release-latest-default-on
Jun 24, 2026
Merged

fix(release): default to moving latest tag; require typed phrase to skip#36311
sfreudenthaler merged 2 commits into
mainfrom
fix/release-latest-default-on

Conversation

@sfreudenthaler

Copy link
Copy Markdown
Member

Closes: #36310

Problem

The promote-latest job in cicd_6-release.yml was gated on a boolean update_latest checkbox. Default-true or not, latest advancing depended on an operator not unchecking it. Release 26.06.22-02 shipped with it unchecked, so latest silently stalled on 26.06.22-01 (both dotcms/dotcms and dotcms/dotcms-dev) until corrected by hand. The default pull tag shouldn't hinge on human memory.

Change

Replace update_latest (boolean) with skip_latest (free text):

skip_latest:
  description: 'Leave BLANK to update the "latest" Docker tag (default). To skip moving latest, type exactly: DO NOT UPDATE LATEST'
  type: string
  default: ''

Gate becomes:

&& github.event.inputs.skip_latest != 'DO NOT UPDATE LATEST'
  • Default = move latest on every GA release from main. Skipping now takes a deliberate, hard-to-fat-finger action (type the exact phrase), mirroring GitHub's "type the repo name to delete" pattern.
  • Fail-safe direction: blank, a typo, or wrong casing all still move latest. The only way to skip is the exact string.
  • Back-patches need no opt-out: the evergreen-tracks engine is forward-only, so promote --tracks latest on an older release line is a no-op (it only ever advances to the newest eligible GA).
  • Runtime freeze unchanged: hold latest via cicd_evergreen-tracks-admin.yml still freezes the track without blocking standard/trailing.

Comparison is done in an if: expression (not interpolated into a run:), so no shell-injection surface from the free-text input.

Notes

update_latest had no other consumers (no docs, scripts, or other workflows referenced it), so the rename is self-contained.

🤖 Generated with Claude Code

Replace the update_latest boolean checkbox with a free-text skip_latest
field. latest now advances on every GA release from main by default;
skipping requires typing the exact phrase "DO NOT UPDATE LATEST". Any
other value (blank, typo) still moves latest — fail-safe to the default.

Reliability of the default pull tag no longer depends on an operator
remembering not to uncheck a box (which silently stalled latest on
26.06.22-02). Back-patches need no opt-out: the evergreen-tracks engine
is forward-only, so promote --tracks latest on an older release is a
no-op. Runtime freeze remains available via the admin `hold latest`.

Closes: #36310

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oEATTqepwGVAMXPJpSqoy
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@claude

claude Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Claude finished @sfreudenthaler's task in 53s —— View job


Rollback Safety Analysis

  • Read rollback-unsafe categories reference
  • Get full PR diff
  • Analyze diff against unsafe categories
  • Apply appropriate label

Result: ✅ Safe To Rollback

The diff is exclusively a GitHub Actions workflow change (.github/workflows/cicd_6-release.yml). No database migrations, Elasticsearch mappings, data model changes, API contract changes, or any other category from the rollback-unsafe reference is touched.

Checklist against all categories:

Category Match?
C-1 Structural Data Model Change ✅ No — no DB changes
C-2 Elasticsearch Mapping Change ✅ No — no ES changes
C-3 Content JSON Serialization Version Bump ✅ No — no contentlet_as_json changes
C-4 DROP TABLE / DROP Column ✅ No — no DDL
H-1 One-Way Data Migration ✅ No — no data transforms
H-2 RENAME TABLE / COLUMN ✅ No — no DDL
H-3 PK Restructuring ✅ No — no DDL
H-4 New ContentType Field Type ✅ No — no field types
H-5 Binary Storage Provider Change ✅ No — no storage changes
H-6 DROP PROCEDURE / FUNCTION ✅ No — no DDL
H-7 NOT NULL column without default ✅ No — no DDL
H-8 VTL Viewtool Contract Change ✅ No — no viewtools
M-1 Non-Broadening Column Type Change ✅ No — no DDL
M-2 Push Publishing Bundle Format Change ✅ No — no bundle changes
M-3 REST / GraphQL API Contract Change ✅ No — no API changes
M-4 OSGi Plugin API Breakage ✅ No — no OSGi changes

The change replaces a boolean update_latest input with a string skip_latest input in the release workflow, and adds an input validation step to verify-branch. Rolling back to the previous release would simply restore the old update_latest boolean — no application state, data, or infrastructure is affected.

Label added: AI: Safe To Rollback

@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — qwen.qwen3-next-80b-a3b

New Issues

  • 🟡 Medium: .github/workflows/cicd_6-release.yml:176 — Logic for skip_latest input validation assumes any non-exact string (including empty or typo’d) still triggers latest update; this is a fail-safe by design but introduces risk of accidental promotion if user types anything other than the exact phrase. Assumption: GitHub Actions input matching is case-sensitive and exact-match only. What to verify: Does GitHub Actions trim whitespace or normalize input before comparison? If yes, " DO NOT UPDATE LATEST " or "do not update latest" could accidentally trigger promotion.

Run: #28120080882 · tokens: in: 1744 · out: 196 · total: 1940

…pdating

Add a verify-branch validation step that fails the release when skip_latest
is neither blank nor exactly "DO NOT UPDATE LATEST". A near-miss like
"do not update latest" now errors and forces a deliberate re-run, rather
than silently falling through to updating latest. Input passed via env to
avoid expression injection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oEATTqepwGVAMXPJpSqoy
@sfreudenthaler

Copy link
Copy Markdown
Member Author

Updated per review: a near-miss in skip_latest now errors instead of silently updating latest.

Added a Validate skip_latest input step to the fail-fast verify-branch job:

- name: Validate skip_latest input
  env:
    SKIP_LATEST: ${{ github.event.inputs.skip_latest }}
  run: |
    if [ -n "${SKIP_LATEST}" ] && [ "${SKIP_LATEST}" != "DO NOT UPDATE LATEST" ]; then
      echo "::error::skip_latest must be blank (update the latest tag) or exactly 'DO NOT UPDATE LATEST' (skip it). Got: '${SKIP_LATEST}'. Re-run with a valid value."
      exit 1
    fi

Three states, no ambiguity:

  • blank → update latest (default)
  • DO NOT UPDATE LATEST (exact) → skip
  • anything else (e.g. do not update latest, trailing space) → fail the release, operator re-runs with a valid value

verify-branch is upstream of everything (initializerelease-prepare → …), so an invalid value stops the release immediately. Value is read via env:, not interpolated into the script, so no injection surface.

@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — qwen.qwen3-next-80b-a3b

New Issues

  • 🟡 Medium: .github/workflows/cicd_6-release.yml:176 — Logic for skip_latest input validation assumes any non-exact string triggers latest update; risk of accidental promotion if input is trimmed or case-insensitive
    Assumption: GitHub Actions input values are not automatically trimmed or normalized before being passed to github.event.inputs.skip_latest.
    What to verify: Does GitHub Actions trim whitespace or normalize case of workflow inputs? If yes, "DO NOT UPDATE LATEST " or "do not update latest" could bypass the check.

Existing

  • 🟡 Medium: .github/workflows/cicd_6-release.yml:176 — Prior finding still present (unchanged or incomplete fix)

Resolved

  • .github/workflows/cicd_6-release.yml:87-95 — Input validation now explicitly rejects non-exact values, eliminating silent fall-through to "update latest"

Run: #28120372080 · tokens: in: 2089 · out: 269 · total: 2358

@sfreudenthaler

Copy link
Copy Markdown
Member Author

Fine with non-exact values failing the release job. don't need the permutations of typos covered, just have the operator redo the release

@sfreudenthaler sfreudenthaler enabled auto-merge June 24, 2026 18:29

@wezell wezell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, added a nit.

Comment thread .github/workflows/cicd_6-release.yml
@sfreudenthaler sfreudenthaler added this pull request to the merge queue Jun 24, 2026
@mergify

mergify Bot commented Jun 24, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

Merged via the queue into main with commit 1292b6e Jun 24, 2026
45 checks passed
@sfreudenthaler sfreudenthaler deleted the fix/release-latest-default-on branch June 24, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : CI/CD PR changes GitHub Actions/workflows

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Release: make moving the latest Docker tag the default; require typed phrase to skip

2 participants