Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions .github/workflows/maint-61-create-floating-v1-tag.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
name: Maint 61 Create Floating v1 Tag

# DEPRECATED: This workflow is disabled in favor of maint-73-refresh-reusable-tags.yml
# which tracks main HEAD instead of releases for immediate fix propagation.
# The v1 tag now follows a main-tracking strategy, not a release-tracking strategy.

on:
workflow_dispatch:
schedule:
- cron: "30 3 * * *"
release:
types:
- published
inputs:
deprecated_notice:
description: 'DEPRECATED - Use maint-73-refresh-reusable-tags.yml instead'
required: false
type: string
# Disabled triggers - use maint-73 for tag updates
# schedule:
# - cron: "30 3 * * *"
# release:
# types:
# - published

permissions:
contents: write
Expand Down
106 changes: 106 additions & 0 deletions .github/workflows/maint-73-refresh-reusable-tags.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Maint 73 Refresh Reusable Tags

# Keep floating tags aligned with main so consumer repos always run the latest
# reusable workflows without editing every repo.
# NOTE: This replaces the release-tracking strategy from maint-61. The v1 tag
# now tracks main HEAD for immediate fix propagation, not latest v1.x release.

on:
push:
branches: [main]
workflow_dispatch:
inputs:
tags:
description: 'Comma-separated tag names to refresh (default: v1)'
required: false
type: string

permissions:
contents: write

concurrency:
group: refresh-reusable-tags-${{ github.ref }}
cancel-in-progress: true

jobs:
refresh:
name: Refresh floating tags
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Configure git
run: |
set -euo pipefail
git config user.name "stranske-automation-bot"
git config user.email "stranske-automation-bot@users.noreply.github.com"

- name: Determine tags
id: tags
run: |
set -euo pipefail
input_tags="${{ inputs.tags }}"
if [ -z "$input_tags" ]; then
input_tags="v1"
fi
tags=$(echo "$input_tags" | tr ',' '\n' | sed 's/^ *//;s/ *$//' | grep -v '^$' | sort -u)
echo "tags<<EOF" >> "$GITHUB_OUTPUT"
echo "$tags" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"

- name: Refresh tags
id: refresh
env:
TAGS: ${{ steps.tags.outputs.tags }}
TARGET_SHA: ${{ github.sha }}
run: |
set -euo pipefail
updated=0
while read -r tag; do
if [ -z "$tag" ]; then
continue
fi
current=$(git rev-parse -q --verify "refs/tags/$tag" || echo "")
if [ "$current" = "$TARGET_SHA" ]; then
echo "Tag $tag already at $TARGET_SHA"
continue
fi
git tag -f "$tag" "$TARGET_SHA"
updated=$((updated + 1))
done <<< "$TAGS"

if [ "$updated" -eq 0 ]; then
echo "No tag updates needed."
exit 0
fi

echo "updated=$updated" >> "$GITHUB_OUTPUT"

while read -r tag; do
if [ -n "$tag" ]; then
git push origin "refs/tags/$tag" --force
fi
done <<< "$TAGS"

- name: Summary
if: always()
env:
TAGS: ${{ steps.tags.outputs.tags }}
UPDATED: ${{ steps.refresh.outputs.updated || '0' }}
run: |
{
echo "## Reusable Tag Refresh"
echo ""
if [ "$UPDATED" -eq 0 ]; then
echo "No updates needed - tags already at ${{ github.sha }}"
else
echo "Updated $UPDATED tag(s) to ${{ github.sha }}:"
echo ""
while IFS= read -r tag; do
[ -n "$tag" ] && echo "- $tag"
done <<< "$TAGS"
fi
} >> "$GITHUB_STEP_SUMMARY"
2 changes: 1 addition & 1 deletion docs/COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Breaking changes are any change that can alter a consumer’s behavior without t

We support at least two major versions at any given time:

- **Current major (v1.x)** – Actively maintained with fixes and backward-compatible enhancements. Floating tag `@v1` points to the latest v1.x release.
- **Current major (v1.x)** – Actively maintained with fixes and backward-compatible enhancements. Floating tag `@v1` tracks the latest commit on `main` (updated automatically by `Maint 73 Refresh Reusable Tags` after every merge) for immediate fix propagation to consumer repos.
- **Previous major** – Remains supported for a minimum of 12 months after a new major is released. Only critical fixes and security updates are provided.
- **Older majors** – Enter end-of-life (EOL) after the 12-month overlap window.

Expand Down
6 changes: 3 additions & 3 deletions docs/INTEGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ Choose the reference that matches your stability needs:

| Reference | When to use it | Behavior |
|-----------|----------------|----------|
| **Floating major tag (`@v1`)** | Default for most teams that want security/bug fixes without breaking changes. | Automatically moves forward to the latest `v1.x` release; maintained by the release workflow and the floating-tag maintenance job. |
| **Pinned release (`@v1.0.0`)** | When you need fully reproducible builds or plan to upgrade on your own schedule. | Locked to a specific release until you update the tag. |
| **Branch reference (`@main`)** | Only when testing unreleased changes. | Can include breaking changes; not guaranteed stable. |
| **Floating major tag (`@v1`)** | Default for most teams that want immediate security/bug fixes. | Automatically tracks the latest commit on `main` (not a release); maintained by `Maint 73 Refresh Reusable Tags` after every merge. Provides immediate fix propagation but may include unreleased changes. |
| **Pinned release (`@v1.0.0`)** | When you need fully reproducible builds or prefer to upgrade on your own schedule. | Locked to a specific release until you update the tag. Recommended for production stability. |
| **Branch reference (`@main`)** | Only when testing unreleased changes or developing new features. | Can include breaking changes; not guaranteed stable. |

Example with both floating and pinned tags:

Expand Down
1 change: 1 addition & 0 deletions docs/ci/WORKFLOWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ Scheduled health jobs keep the automation ecosystem aligned:
* [`maint-69-sync-integration-repo.yml`](../../.github/workflows/maint-69-sync-integration-repo.yml) syncs integration-repo templates to Workflows-Integration-Tests repository (template push, manual dispatch with dry-run support).
* [`maint-69-sync-labels.yml`](../../.github/workflows/maint-69-sync-labels.yml) syncs core functional labels from labels-core.yml to consumer repos (push to labels-core.yml, manual dispatch with dry-run support).
* [`maint-70-fix-integration-formatting.yml`](../../.github/workflows/maint-70-fix-integration-formatting.yml) applies Black and Ruff formatting fixes to Integration-Tests repository files (manual dispatch for CI formatting failures).
* [`maint-73-refresh-reusable-tags.yml`](../../.github/workflows/maint-73-refresh-reusable-tags.yml) auto-refreshes floating tags (v1) to track main HEAD - ensures consumer repos always run latest reusable workflow versions without manual updates (push to main, manual dispatch). Replaces deprecated maint-61.
* [`maint-71-auto-fix-integration.yml`](../../.github/workflows/maint-71-auto-fix-integration.yml) automatically applies formatting fixes to Integration-Tests when triggered by issue comments or workflow failures.
* [`maint-71-merge-sync-prs.yml`](../../.github/workflows/maint-71-merge-sync-prs.yml) automates merging sync PRs in consumer repos - checks status, merges passing PRs, cleans up stale PRs (manual dispatch).
* [`maint-72-fix-pr-body-conflicts.yml`](../../.github/workflows/maint-72-fix-pr-body-conflicts.yml) removes pr_body.md from main branch and adds to .gitignore across consumer repos - prevents merge conflicts from PR description files (manual dispatch, weekly schedule).
Expand Down
1 change: 1 addition & 0 deletions docs/ci/WORKFLOW_SYSTEM.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ Keep this table handy when you are triaging automation: it confirms which workfl
| **Maint 69 Sync Integration Repo** (`maint-69-sync-integration-repo.yml`, maintenance bucket) | `push` (templates), `workflow_dispatch` | Sync integration-repo templates to Workflows-Integration-Tests repository. Resolves drift detected by Health 67. Supports dry-run mode. | ⚪ Automatic/manual | [Integration sync runs](https://github.com/stranske/Workflows/actions/workflows/maint-69-sync-integration-repo.yml) |
| **Maint 69 Sync Labels** (`maint-69-sync-labels.yml`, maintenance bucket) | `push` (labels-core.yml), `workflow_dispatch` | Sync core functional labels from labels-core.yml to consumer repositories. Distinguishes functional workflow labels from informational repo-specific labels. Supports dry-run mode. | ⚪ Automatic/manual | [Label sync runs](https://github.com/stranske/Workflows/actions/workflows/maint-69-sync-labels.yml) |
| **Fix Integration Tests Formatting** (`maint-70-fix-integration-formatting.yml`, maintenance bucket) | `workflow_dispatch` | Manually triggered workflow to apply Black and Ruff formatting fixes to Python files in the Workflows-Integration-Tests repository when CI formatting checks fail. | ⚪ Manual only | [Formatting fix runs](https://github.com/stranske/Workflows/actions/workflows/maint-70-fix-integration-formatting.yml) |
| **Maint 73 Refresh Reusable Tags** (`maint-73-refresh-reusable-tags.yml`, maintenance bucket) | `push` (main branch), `workflow_dispatch` | Auto-refreshes floating tags (v1) to track main HEAD, ensuring consumer repos always execute latest reusable workflow versions without editing references. Replaces deprecated maint-61. | 🟢 Automated | [Tag refresh runs](https://github.com/stranske/Workflows/actions/workflows/maint-73-refresh-reusable-tags.yml) |
| **Auto-Fix Integration Test Failures** (`maint-71-auto-fix-integration.yml`, maintenance bucket) | `issues` (labeled), `workflow_run` (failed) | Automatically applies Black and Ruff formatting fixes to Python files in the Workflows-Integration-Tests repository when triggered by issue labels or workflow failures. | 🟢 Automated | [Auto-fix runs](https://github.com/stranske/Workflows/actions/workflows/maint-71-auto-fix-integration.yml) |
| **Merge Sync PRs** (`maint-71-merge-sync-prs.yml`, maintenance bucket) | `workflow_dispatch`, `workflow_call` | Automates merging sync PRs across consumer repos. Checks CI status, merges passing PRs, cleans up stale sync PRs. Reads consumer repo list from maint-68-sync-consumer-repos.yml. | ⚪ Manual/callable | [Merge sync runs](https://github.com/stranske/Workflows/actions/workflows/maint-71-merge-sync-prs.yml) |
| **Maint 72 Fix PR Body Conflicts** (`maint-72-fix-pr-body-conflicts.yml`, maintenance bucket) | `workflow_dispatch`, `schedule` (weekly) | Removes `pr_body.md` from main and adds to `.gitignore` in consumer repos to prevent merge conflicts. | ⚪ Manual/scheduled | [PR body fix runs](https://github.com/stranske/Workflows/actions/workflows/maint-72-fix-pr-body-conflicts.yml) |
Expand Down
17 changes: 17 additions & 0 deletions docs/ops/CONSUMER_REPO_MAINTENANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,23 @@ Maint 68 is manifest-driven:

Custom Gate repos are a special-case skip: their `pr-00-gate.yml` stays local.

### Reusable Workflow Versioning

Consumer repos call reusable workflows via a floating tag (currently `v1`).
`Maint 73 Refresh Reusable Tags` automatically advances those tags to the
current `main` SHA after every merge, so consumers always execute the latest
reusable workflow logic without manual version bumps.

**Version Strategy Change**: This differs from the older behavior documented in
`docs/INTEGRATION_GUIDE.md`, where `@v1` was documented as floating to the latest
`v1.x` release maintained by the release workflow (`maint-61`). Consumer repos now
use a **main-HEAD tracking** strategy for immediate fix propagation. For repos that
need extra stability, pin to a specific commit SHA instead of the floating `v1` tag.

If a reusable workflow fix must ship immediately, trigger:
- `Maint 73 Refresh Reusable Tags` (updates `v1`; replaces deprecated `maint-61`)
- `Maint 68 Sync Consumer Repos` only if template files changed

### Manual Sync Trigger

```bash
Expand Down
10 changes: 8 additions & 2 deletions tests/workflows/fixtures/keepalive/harness.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,15 @@ async function runScenario(scenario) {
},
};

const clearTokenDefaults =
Boolean(scenario.clear_token_defaults) ||
Boolean(scenario.clearTokenDefaults) ||
Boolean(scenario.env?.CLEAR_TOKEN_DEFAULTS) ||
Boolean(scenario.env?.clear_token_defaults);

const envOverrides = {
ACTIONS_BOT_PAT: 'dummy-token',
SERVICE_BOT_PAT: 'service-token',
ACTIONS_BOT_PAT: clearTokenDefaults ? '' : 'dummy-token',
SERVICE_BOT_PAT: clearTokenDefaults ? '' : 'service-token',
GH_TOKEN: '',
gh_token: '',
actions_bot_pat: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"repo": {"owner": "stranske", "repo": "Workflows"},
"now": "2024-05-18T12:00:00Z",
"clear_token_defaults": true,
"env": {
"OPTIONS_JSON": "{}",
"DRY_RUN": "false",
Expand Down
1 change: 1 addition & 0 deletions tests/workflows/test_workflow_naming.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ def test_workflow_display_names_are_unique():
"maint-68-sync-consumer-repos.yml": "Maint 68 Sync Consumer Repos",
"maint-69-sync-integration-repo.yml": "Maint 69 Sync Integration Repo",
"maint-69-sync-labels.yml": "Maint 69 Sync Labels",
"maint-73-refresh-reusable-tags.yml": "Maint 73 Refresh Reusable Tags",
"maint-60-release.yml": "Maint 60 Release",
"maint-70-fix-integration-formatting.yml": "Fix Integration Tests Formatting",
"maint-71-auto-fix-integration.yml": "Auto-Fix Integration Test Failures",
Expand Down
Loading