Skip to content

Promote main to lts#1159

Closed
github-actions[bot] wants to merge 20 commits intoltsfrom
main
Closed

Promote main to lts#1159
github-actions[bot] wants to merge 20 commits intoltsfrom
main

Conversation

@github-actions
Copy link

@github-actions github-actions bot commented Mar 3, 2026

Summary

Promotion of tested changes from to production branch.

IMPORTANT: This PR should ONLY contain commits from → . Never merge in the opposite direction.

ubot-7274 bot and others added 20 commits March 1, 2026 18:13
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[actions/download-artifact](https://redirect.github.com/actions/download-artifact)
| action | major | `v7` → `v8` |
|
[actions/upload-artifact](https://redirect.github.com/actions/upload-artifact)
| action | major | `v6` → `v7` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Release Notes

<details>
<summary>actions/download-artifact (actions/download-artifact)</summary>

###
[`v8`](https://redirect.github.com/actions/download-artifact/compare/v7...v8)

[Compare
Source](https://redirect.github.com/actions/download-artifact/compare/v7...v8)

</details>

<details>
<summary>actions/upload-artifact (actions/upload-artifact)</summary>

###
[`v7`](https://redirect.github.com/actions/upload-artifact/compare/v6...v7)

[Compare
Source](https://redirect.github.com/actions/upload-artifact/compare/v6...v7)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [x] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40My4wIiwidXBkYXRlZEluVmVyIjoiNDMuNDMuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
…t to b8fe93b (#1133)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| ghcr.io/projectbluefin/common | digest | `5decea8` → `b8fe93b` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [x] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4zOC4xIiwidXBkYXRlZEluVmVyIjoiNDMuMzguMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [anchore/sbom-action](https://redirect.github.com/anchore/sbom-action)
([changelog](https://redirect.github.com/anchore/sbom-action/compare/28d71544de8eaf1b958d335707167c5f783590ad..17ae1740179002c89186b61233e0f892c3118b11))
| action | digest | `28d7154` → `17ae174` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [x] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4zOC4xIiwidXBkYXRlZEluVmVyIjoiNDMuMzguMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
…est to 7dca424 (#1131)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| quay.io/centos-bootc/centos-bootc | digest | `001a05c` → `7dca424` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [x] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4zMS45IiwidXBkYXRlZEluVmVyIjoiNDMuMzEuOSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
## Summary
This PR ensures SBOMs are only generated on the `lts` production branch,
not on `main` branch or pull requests.

## Problem
The `build-dx-hwe.yml` workflow had inconsistent SBOM generation logic
compared to all other build workflows:
- **build-dx-hwe.yml**: Generated SBOMs on main branch (incorrect)
- **All other workflows**: Only generated SBOMs on lts branch (correct)

## Solution
Aligned `build-dx-hwe.yml` SBOM logic with the other 4 workflows:
```yaml
sbom: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/lts' }}
```

## Impact
After this change, SBOMs will **only** be generated when:
- ✅ Event is NOT a pull request
- ✅ Branch is `lts` (production branch)
- ❌ Branch is `main` (testing branch) - **NO SBOMs**
- ❌ Pull requests to any branch - **NO SBOMs**

## Testing
- [ ] Syntax validation passes
- [ ] Logic matches other workflows:
  - build-regular.yml ✅
  - build-regular-hwe.yml ✅
  - build-dx.yml ✅
  - build-gdx.yml ✅
  - build-dx-hwe.yml ⚠️ (fixed by this PR)
## Summary
This reverts commit 16aa2b3 (PR #1140) to restore the original SBOM
generation behavior.

## Reason for Revert
The previous PR was merged without proper review. Opening this revert so
the change can be properly reviewed by Copilot and maintainers before
proceeding.

## What This Revert Does
Restores the original SBOM generation logic in all workflow files:
- `build-dx-hwe.yml` - back to generating SBOMs on main branch
- All other workflows - back to their previous state

## Next Steps
After this revert is merged, a new PR will be opened with the SBOM fix
for proper review.
## Summary
This PR ensures SBOMs are only generated on the `lts` production branch,
not on `main` branch or pull requests.

## Problem
The `build-dx-hwe.yml` workflow currently generates SBOMs on all non-PR
builds, including the `main` branch. This is inconsistent with the other
build workflows which only generate SBOMs on the `lts` production
branch.

### Current State
| Workflow | SBOM Generation Logic | Generates on main? |
|----------|----------------------|-------------------|
| build-regular.yml | `github.event_name != 'pull_request' && github.ref
== 'refs/heads/lts'` | ❌ No |
| build-regular-hwe.yml | `github.event_name != 'pull_request' &&
github.ref == 'refs/heads/lts'` | ❌ No |
| build-dx.yml | `github.event_name != 'pull_request' && github.ref ==
'refs/heads/lts'` | ❌ No |
| build-gdx.yml | `github.event_name != 'pull_request' && github.ref ==
'refs/heads/lts'` | ❌ No |
| **build-dx-hwe.yml** | `github.event_name != 'pull_request'` | ⚠️
**Yes** (inconsistent) |

## Solution
Align `build-dx-hwe.yml` with the other workflows:

```yaml
sbom: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/lts' }}
```

## Impact
After this change, SBOMs will **only** be generated when:
- ✅ Event is NOT a pull request
- ✅ Branch is `lts` (production branch per `reusable-build-image.yml`
line 76)

SBOMs will **NOT** be generated when:
- ❌ Branch is `main` (testing branch per `reusable-build-image.yml` line
77)
- ❌ Event is a pull request

## Testing
- [x] Syntax validation: Change aligns with existing pattern in 4 other
workflows
- [x] Logic verified: All 5 workflows will have identical SBOM
generation logic
- [x] Conventional commit format used

## Checklist
- [x] Change is minimal and surgical
- [x] Conventional commit message used
- [x] AI attribution included in commit footer
## Summary
This prevents automatic builds/publishes on lts branch from pull app
promotions while maintaining the ability to manually trigger releases.

## Changes
- ✅ Remove `lts` from push triggers (keeps `main` only)
- ✅ Add weekly cron schedule (Sunday 2 AM UTC) for all 5 build workflows
- ✅ Conditional publish: only on `lts` if scheduled or manual dispatch
- ✅ PRs to `lts` still validate (build without publish)
- ✅ `main` branch continues to build/publish to `:lts-testing`

## Benefits
- 🚫 No accidental production releases from pull app merges
- 📅 Controlled weekly production releases via cron
- 🎯 Manual release capability via workflow_dispatch
- 📝 Proper changelog generation when GDX build completes on schedule

## Testing
- [x] Syntax validated with `just check`
- [x] Shellcheck linting passed
- [ ] Should test with manual workflow_dispatch on `lts` branch after
merge

## Related
Fixes the issue where changelogs weren't being generated because builds
on `lts` were happening from pull app promotions instead of
scheduled/manual runs.
…est to d4ef607 (#1139)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| quay.io/centos-bootc/centos-bootc | digest | `7dca424` → `d4ef607` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40Ni42IiwidXBkYXRlZEluVmVyIjoiNDMuNDYuNiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
…1068 (#1135)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| ghcr.io/ublue-os/brew | digest | `3efdc1a` → `ca91068` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40Ni4zIiwidXBkYXRlZEluVmVyIjoiNDMuNDYuNiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
…est to d4ef607 (#1145)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| quay.io/centos-bootc/centos-bootc | digest | `7dca424` → `d4ef607` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled because a matching PR was automerged
previously.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40Ni42IiwidXBkYXRlZEluVmVyIjoiNDMuNDYuNiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
…t to cbe78e6 (#1146)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| ghcr.io/projectbluefin/common | digest | `b8fe93b` → `cbe78e6` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40Ny4wIiwidXBkYXRlZEluVmVyIjoiNDMuNDcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
## Summary

This PR fixes accidental production tag publishes from pull bot PRs to
the `lts` branch by implementing a dispatcher pattern for scheduled
releases.

### Changes Made

1. **Created dispatcher workflow** (`scheduled-lts-release.yml`)
   - Runs weekly on Sunday at 2 AM UTC
- Triggers all 5 build workflows on `lts` branch via `workflow_dispatch`
- Solves the problem that GitHub Actions `schedule:` triggers always run
on default branch

2. **Updated all 5 build workflows**:
- Removed `lts` from `pull_request:` triggers (no longer trigger on pull
bot PRs)
- Added `lts` to `push:` triggers (validation builds on pull bot merges)
   - Removed `schedule:` sections (moved to dispatcher)
   - Updated `publish:` conditions to only publish on:
     - `workflow_dispatch` events (cron dispatcher + manual triggers)
     - `push` to `main` branch (`:lts-testing` tags)

### Workflow Behavior Matrix

| Event | Branch | Triggers? | Publishes? | Tags |
|-------|--------|-----------|------------|------|
| PR to main | `main` | ✅ | ❌ | none |
| Merge to main | `main` | ✅ | ✅ | `:lts-testing` |
| PR to lts | `lts` | ❌ | ❌ | none |
| Merge to lts | `lts` | ✅ | ❌ | none (validation only) |
| Cron Sun 2am | `main` | ✅ | ❌ | none (dispatcher) |
| Dispatcher | `lts` | ✅ | ✅ | `:lts` (production) |
| Manual dispatch | `lts` | ✅ | ✅ | `:lts` |

### Problem Fixed

**Before:** Pull bot PRs to `lts` triggered all 5 build workflows and
published production tags (`:lts`, `:lts.YYYYMMDD`)

**After:** Pull bot PRs to `lts` do NOT trigger workflows. Production
tags only publish via:
- Weekly cron schedule (Sunday 2 AM UTC)
- Manual `workflow_dispatch` on `lts` branch

**Evidence of bug:** PR #1144 (pull bot) triggered runs:
- #22586907105 (Build Bluefin LTS)
- #22586905020 (Build Bluefin LTS DX) 
- #22586905071 (Build Bluefin LTS GDX)

All published production tags from PR event instead of scheduled event.

### Testing Plan

After merge, need to verify:
- [ ] Pull bot PRs to `lts` do NOT trigger workflows
- [ ] Pull bot merges to `lts` DO trigger validation builds but do NOT
publish
- [ ] Manual dispatcher trigger works and publishes production tags
- [ ] Merges to `main` still publish `:lts-testing` tags

### Branch Protection Update Required

The `lts` branch protection needs manual updates (web UI or API):
- Change required approvals from 2 → 1
- Disable force pushes (currently enabled)
- Enable conversation resolution
- Enable dismiss stale reviews

Current settings:
```json
{
  "approvals": 2,
  "force_pushes": true,
  "enforce_admins": false
}
```

### Related Issues

Fixes the accidental production tag publishing issue observed on
2026-03-02.

### Implementation Notes

- All commits follow conventional commit format
- Syntax validated with `just check`
- Linting validated with `just lint` (no new warnings introduced)
- Plan documented in `docs/plans/2026-03-02-fix-lts-tag-publishing.md`
…orkflow (#1152)

## Summary

This PR implements a comprehensive 3-layer defense to prevent branch
pollution caused by AI agents accidentally merging `lts` → `main`.

### Problem
AI agents see branch divergence between `main` and `lts` and attempt to
"sync" by merging in the wrong direction (`lts` → `main`), causing old
commits to pollute the git history.

### Solution: 3-Layer Defense

**Layer 1: Manual Promotion Workflow**
- Replace automatic Pull app with manual GitHub Actions workflow
- Created `.github/workflows/promote-to-lts.yml` (manual
`workflow_dispatch` only)
- Deleted `.github/pull.yml` (automatic pull app config)
- Operators manually trigger promotions when ready

**Layer 2: Renovate Restriction**
- Updated `.github/renovate.json5` to only target `main` branch
- Prevents Renovate from creating PRs against `lts`
- All dependency updates flow through `main` → testing → promotion

**Layer 3: Validation Build Triggers** (Critical Fix)
- Added `lts` to push triggers in all 5 build workflows
- Fixes missing implementation from commit 8ed6d20
- Enables validation builds when promotion PRs merge to `lts`
- Builds trigger but **DO NOT publish** (cron-only publishing preserved)

### Workflow Behavior After This PR

| Event | Branch | Triggers? | Publishes? | Tags |
|-------|--------|-----------|------------|------|
| PR to main | main | ✅ | ❌ | none |
| Merge to main | main | ✅ | ✅ | `:lts-testing` |
| PR to lts | lts | ❌ | ❌ | none |
| **Merge to lts** | **lts** | **✅** | **❌** | **validation only** |
| Cron Sun 2am | main | ✅ (dispatcher) | ❌ | none |
| Dispatcher trigger | lts | ✅ | ✅ | `:lts` (production) |

### Decoupled Promotion & Release

**Promotion** (manual):
1. Operator triggers `promote-to-lts.yml` workflow
2. PR auto-created from `main` → `lts`
3. Operator reviews and merges
4. Validation builds trigger (no publish)

**Release** (separate):
1. Sunday cron OR manual trigger
2. `scheduled-lts-release.yml` dispatches builds on `lts`
3. Production images published to ghcr.io with `:lts` tags

### Changes Made

```
8 files changed, 70 insertions(+), 16 deletions(-)
```

- ✅ Deleted `.github/pull.yml`
- ✅ Created `.github/workflows/promote-to-lts.yml`
- ✅ Updated `.github/renovate.json5` (added `baseBranches: ["main"]`)
- ✅ Modified 5 build workflows (added `lts` to push triggers)

### Testing

- ✅ `just check` passed
- ✅ `just lint` passed (no new warnings)
- 📋 After merge: Test promotion workflow creates PR correctly
- 📋 After merge: Test validation builds trigger on lts merge (no
publish)

### Post-Merge Actions

- [ ] Manually uninstall Pull app from repository settings (user will
handle)
- [ ] Test promotion workflow via Actions → "Promote Main to LTS"
- [ ] Verify validation builds trigger without publishing

### Related

Fixes the branch pollution issue and completes the missing
implementation from commit 8ed6d20.

Plan documented at: `docs/plans/2026-03-02-fix-branch-pollution.md`
…t to 786c4d1 (#1149)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| cgr.dev/chainguard/wolfi-base | container | digest | `9925d30` →
`786c4d1` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40OC4zIiwidXBkYXRlZEluVmVyIjoiNDMuNDguMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
…/caffeine digest to 98b3b4f (#1148)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
|
[system_files/usr/share/gnome-shell/extensions/tmp/caffeine](https://redirect.github.com/eonpatapon/gnome-shell-extension-caffeine.git)
([changelog](https://redirect.github.com/eonpatapon/gnome-shell-extension-caffeine.git/compare/07643c383db62dfcbb0485f344d063389644f2f9..98b3b4f60247d61b8d93acdd6055d5b41adbbb24))
| digest | `07643c3` → `98b3b4f` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/549) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40OC4yIiwidXBkYXRlZEluVmVyIjoiNDMuNDguMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com>
…#1154)

## Summary

Fixes a critical bug where merges to `main` branch were accidentally
pushing container images to the production `:lts` tag instead of the
testing `:lts-testing` tag.

## Problem

The manifest generation step (line 372) had incorrect conditional logic:
- **Build step (line 161)**: Simple condition `if [ "${REF_NAME}" !=
"${PRODUCTION_BRANCH}" ]` - adds `-testing` for all non-production
branches ✅
- **Manifest step (line 372)**: Complex condition that only added
`-testing` for PRs/merge groups - omitted pushes to main ❌

This caused:
- Build step creates image tagged `lts-testing` ✅
- Manifest step pushes manifest with tag `lts` ❌
- **Result**: Production tag gets polluted with testing builds!

## Solution

- Line 372: Changed from complex condition to simple `if [ "${REF_NAME}"
!= "${PRODUCTION_BRANCH}" ]` to match build step logic
- Line 375: Fixed `CENTOS_VERSION_SUFFIX` to append suffix instead of
replacing (preserves `-hwe` when present)

## Evidence

- Bug introduced in commit `0566080` (PR #1101) which fixed the build
step but forgot the manifest step
- Registry shows `:lts-testing` tags exist but haven't been updated
since Feb 22 (builds were cancelled)
- Production `:lts` tags show recent activity through Mar 2

## Verification

- ✅ `just check && just lint` passes
- ✅ Test script confirms push to main will now tag as `lts-testing` not
`lts`
## Summary

- **Fix tag pollution from main branch merges**: The manifest step had
complex conditional logic that omitted pushes to `main`, causing `:lts`
production tags to be overwritten by testing builds. Aligns manifest
step with build step logic.
- **Fix `Push Manifest` and `sign` failing on lts push events**: Both
steps used `github.event_name != 'pull_request'` which fired even when
`publish=false`, causing `image not known` errors. Now gated on
`inputs.publish`.
- **Remove duplicate `schedule:` from all 5 build workflows**: The
dispatcher (`scheduled-lts-release.yml`) owns the weekly cron. The stale
entries were triggering 10 extra no-op builds on `main` every Sunday on
top of the 5 dispatcher runs on `lts`.
- **Simplify `promote-to-lts.yml`**: Replace the
checkout+merge+intermediate-branch approach (which reintroduced merge
commit pollution) with a single `gh pr create --base lts --head main`
call. Drops `contents: write` permission.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions github-actions bot requested a review from castrojo as a code owner March 3, 2026 03:38
@github-actions github-actions bot added the promotion This PR is a candidate to promote to `lts`. label Mar 3, 2026
@github-actions github-actions bot requested a review from tulilirockz as a code owner March 3, 2026 03:38
@github-actions github-actions bot added the promotion This PR is a candidate to promote to `lts`. label Mar 3, 2026
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. kind/github-action Anything having to do with GHA and automation labels Mar 3, 2026
@castrojo
Copy link
Collaborator

castrojo commented Mar 3, 2026

Closing in favor of a conflict-resolved replacement PR.

@dosubot
Copy link

dosubot bot commented Mar 3, 2026

Related Documentation

3 document(s) may need updating based on files changed in this PR:

bluefin

Bluefin Newsletter 2.0
View Suggested Changes
@@ -1,7 +1,7 @@
 ## Recent Completed Work
 | Date Completed | Task | Overview | Impact |
 |---|---|---|---|
-| 2026-03-02 | Prevent Branch Pollution with Manual LTS Promotion | A comprehensive three-layer defense was implemented to prevent branch pollution. **Layer 1:** The automated Pull app (`.github/pull.yml`) was removed and replaced with a manual `.github/workflows/promote-to-lts.yml` workflow triggered via workflow_dispatch, requiring manual operator approval for promotions. **Layer 2:** Renovate configuration updated with `baseBranchPatterns: ["main"]` to restrict automated PRs to the main branch only, preventing dependency updates on lts. **Layer 3:** Added `lts` to push triggers in 5 build workflows (build-dx-hwe.yml, build-dx.yml, build-gdx.yml, build-regular-hwe.yml, build-regular.yml) to enable validation builds that catch accidental merges. | Protects production lts branch from automated updates and prevents reverse merges. Ensures controlled, deliberate promotions from main to lts via explicit human action. Validation builds provide safety net against accidental merges without publishing. [Details](https://github.com/ublue-os/bluefin-lts/pull/1152) |
+| 2026-03-02 | Semi-Automated LTS Promotion and Release System | A comprehensive workflow system was implemented to protect the production lts branch while enabling efficient releases. **Layer 1:** The automated Pull app (`.github/pull.yml`) was completely removed and replaced with two workflows: (a) `.github/workflows/promote-to-lts.yml` for manual PR creation from main → lts via workflow_dispatch, ensuring one-way merge direction with proper guardrails, and (b) `.github/workflows/scheduled-lts-release.yml` that runs every Sunday at 2 AM UTC, automatically triggering all 5 build workflows (build-regular, build-dx, build-gdx, build-regular-hwe, build-dx-hwe) on the lts branch for weekly production releases. **Layer 2:** Renovate configuration restricted with `baseBranchPatterns: ["main"]` to prevent automated PRs on lts. **Layer 3:** Push triggers on lts branch enable validation builds (publish=false) when promotion PRs are merged, catching issues before the next scheduled release. Schedule triggers removed from individual build workflows—all scheduled production builds centralized in `scheduled-lts-release.yml`. | Protects production lts branch from automated updates and reverse merges. Decouples promotion from release: maintainers control when main → lts promotions happen, while production releases happen automatically every Sunday or on-demand. Validation builds verify merged code compiles cleanly before production publishing. [Details](https://github.com/ublue-os/bluefin-lts/pull/1152) [Refinement](https://github.com/ublue-os/bluefin-lts/pull/1159) |
 | 2026-02-12 | Expand Renovate Automerge for Container Digests | Renovate automerge now covers digest updates for three additional containers: `quay.io/centos-bootc/bootc-image-builder` (CI tooling), `ghcr.io/ublue-os/akmods-zfs` (ZFS kernel modules), and `ghcr.io/ublue-os/brew` (Homebrew). NVIDIA driver digests remain manual for compatibility review. | Reduces manual PR review for frequent security/bugfix container updates while maintaining CI and branch protections. Improves automation and security posture. [Details](https://github.com/ublue-os/bluefin-lts/pull/1105) |
 | 2026-01-31 | Add ibus-chewing to Bluefin LTS for zh_TW | The ibus-chewing input method is now included in Bluefin LTS, matching the default for the zh_TW locale in Bluefin Stable. This resolves issues where Chewing was configured but not available when installing from older ISOs, and improves the Traditional Chinese typing experience out of the box. | Ensures consistent and functional Traditional Chinese input for zh_TW users on both Stable and LTS. Reduces manual configuration and improves i18n parity. [Details](https://github.com/ublue-os/bluefin-lts/pull/1076) |
 | 2025-12-16 | Reintroduce Renovate Automation | The Renovate dependency automation was restored. The `.github/renovate.json5` configuration was updated to include `ghcr.io/projectbluefin/common` in the automerge dependencies, ensuring that updates to this key dependency are now automatically merged. | Keeps dependencies up to date with less manual intervention, improving security and reliability. [Details](https://github.com/ublue-os/bluefin/pull/3853) |
@@ -24,7 +24,7 @@
 ## Summary Table
 | Date       | Change Summary |
 |------------|---------------|
-| 2026-03-02 | Renovate restricted to main branch; Pull app replaced with manual promotion workflow; validation builds added to lts branch |
+| 2026-03-02 | Pull app removed; semi-automated LTS promotion and release system implemented with manual PR creation and weekly automated production builds |
 | 2026-02-12 | Renovate automerge expanded to cover additional container digests: bootc-image-builder, akmods-zfs, and brew |
 | 2026-01-31 | ibus-chewing input method added to Bluefin LTS for zh_TW locale parity |
 | 2025-12-16 | Renovate automation restored for `ghcr.io/projectbluefin/common` |

[Accept] [Decline]

Bluefin OS
View Suggested Changes
@@ -101,14 +101,14 @@
 
 **Promotion Process:**
 
-Changes flow from `main` to `lts` via the `.github/workflows/promote-to-lts.yml` workflow, which is manually triggered via `workflow_dispatch`. The workflow creates a pull request directly using `gh pr create --base lts --head main`, allowing maintainers to review and approve the promotion. This simplified approach replaced the previous checkout+merge+intermediate-branch method and requires only `pull-requests: write` and `issues: write` permissions (no longer needs `contents: write`).
+Changes flow from `main` to `lts` via the `.github/workflows/promote-to-lts.yml` workflow, which is manually triggered via `workflow_dispatch`. The workflow creates a pull request with the title "Promote main to lts" using `gh pr create --base lts --head main`, allowing maintainers to review and approve the promotion. This approach ensures the merge direction is always `main` → `lts` (never `lts` → `main`) and requires only `pull-requests: write` and `issues: write` permissions. The previous `.github/pull.yml` configuration file has been removed.
 
 **Build Triggers:**
 
 All LTS build workflows (build-dx.yml, build-dx-hwe.yml, build-gdx.yml, build-regular.yml, build-regular-hwe.yml) trigger on both `main` and `lts` branches:
 
 - **Builds on `main`**: Triggered by pushes, pull requests, and merge groups for validation and testing
-- **Builds on `lts`**: Triggered by pushes (including merged promotion PRs) for production releases. Weekly scheduled builds (Sundays at 2 AM UTC) are centralized through a dispatcher workflow (`scheduled-lts-release.yml`), with individual workflow `schedule:` triggers removed to prevent duplicate builds
+- **Builds on `lts`**: Triggered by pushes (including merged promotion PRs) for production releases. Weekly scheduled builds (Sundays at 2 AM UTC) are centralized through a dispatcher workflow (`scheduled-lts-release.yml`) that triggers all 5 build workflows on the `lts` branch via `workflow_dispatch`. Individual workflow `schedule:` cron triggers have been removed to prevent duplicate builds
 
 **Dependency Management:**
 
@@ -119,10 +119,10 @@
 The build workflows have been refined to ensure reliable image publishing:
 
 - **Tag pollution prevention**: The manifest step logic aligns with the build step logic, checking `if [ "${REF_NAME}" != "${PRODUCTION_BRANCH}" ]` to apply the `-testing` suffix consistently. This prevents production tags from being overwritten by testing builds when merging to `main`.
-- **Manifest and signing fixes**: The "Push Manifest" and "sign" steps are now properly gated on `inputs.publish` instead of `github.event_name != 'pull_request'`, which fixes "image not known" errors that previously occurred when these steps fired on validation builds.
+- **Manifest and signing fixes**: The "Push Manifest" and "sign" steps are gated on `inputs.publish`, which fixes "image not known" errors that previously occurred when these steps fired on validation builds.
 - **Default publish behavior**: The `publish` input in `reusable-build-image.yml` defaults to `false` for improved safety, requiring callers to explicitly opt in to image publishing.
 
-SBOM (Software Bill of Materials) artifacts are generated only for builds on the `lts` branch when `inputs.publish` is true (condition: `github.ref == 'refs/heads/lts' && inputs.publish`). All SBOM steps include `continue-on-error: true` to ensure that external service outages (such as Sigstore/Rekor) never block image publishing. The `sbom:` input parameter has been removed from the reusable workflow.
+SBOM (Software Bill of Materials) artifacts are generated only for builds on the `lts` branch when `inputs.publish` is true (condition: `github.ref == 'refs/heads/lts' && inputs.publish`). All SBOM steps include `continue-on-error: true` to ensure that external service outages (such as Sigstore/Rekor) never block image publishing.
 
 ### Rebasing Between Variants
 
@@ -180,9 +180,9 @@
 Build workflows trigger on multiple events to support both development and production workflows:
 
 - **main branch**: Builds triggered by push events, pull requests, and merge groups for validation and testing
-- **lts branch**: Builds triggered by push events (including merged promotion PRs) for production releases. Weekly scheduled builds (Sundays at 2 AM UTC) are centralized through a dispatcher workflow (`scheduled-lts-release.yml`), with individual workflow `schedule:` triggers removed to prevent duplicate builds
-
-All LTS variant build workflows (build-dx.yml, build-dx-hwe.yml, build-gdx.yml, build-regular.yml, build-regular-hwe.yml) trigger on both branches to ensure changes are validated before promotion to production.
+- **lts branch**: Builds triggered by push events (including merged promotion PRs) for production releases. Weekly scheduled builds (Sundays at 2 AM UTC) are centralized through a dispatcher workflow (`scheduled-lts-release.yml`) that triggers all 5 build workflows (build-dx.yml, build-dx-hwe.yml, build-gdx.yml, build-regular.yml, build-regular-hwe.yml) on the `lts` branch via `workflow_dispatch`. Individual workflow `schedule:` cron triggers have been removed to prevent duplicate builds
+
+All LTS variant build workflows trigger on both branches to ensure changes are validated before promotion to production.
 
 ### SBOM Generation
 

[Accept] [Decline]

Universal Blue Build and Update System
View Suggested Changes
@@ -46,30 +46,31 @@
 - Manual `workflow_dispatch` triggers
 
 **LTS branch triggers:**
-- A dispatcher workflow (`scheduled-lts-release.yml`) runs weekly on Sunday at 2 AM UTC on the default branch
-- The dispatcher triggers all 5 build workflows on the `lts` branch via `workflow_dispatch` events
+- The `scheduled-lts-release.yml` dispatcher workflow runs weekly on Sunday at 2 AM UTC (`cron: '0 2 * * 0'`) on the default branch
+- The dispatcher triggers all 5 build workflows (`build-regular.yml`, `build-dx.yml`, `build-gdx.yml`, `build-regular-hwe.yml`, `build-dx-hwe.yml`) on the `lts` branch via `gh workflow run` commands with `--ref lts`
 - Push events to `lts` branch trigger validation builds but do NOT publish production tags
 - Pull requests to `lts` branch do NOT trigger workflows (prevents accidental publishes)
 - Manual `workflow_dispatch` triggers (for emergency releases)
-- Individual build workflows no longer have `schedule:` triggers—the centralized dispatcher eliminates 10 duplicate no-op builds that previously ran on `main` every Sunday alongside the 5 dispatcher runs on `lts`, working around GitHub Actions limitation that scheduled triggers always run on the default branch
+- Individual build workflows no longer have `schedule:` triggers—the centralized dispatcher is the sole owner of scheduled production releases, eliminating duplicate no-op builds and working around GitHub Actions limitation that scheduled triggers always run on the default branch
 
 This architecture prevents accidental production tag publishing while maintaining validation builds on merges. The validation builds on `lts` push events provide a third layer of defense against branch pollution by verifying code integrity when promotion PRs merge.
 
 **Dispatcher Workflow Architecture:**
 
-The dispatcher pattern solves a GitHub Actions constraint where scheduled triggers always execute on the default branch. The `scheduled-lts-release.yml` workflow runs on `main` and uses GitHub CLI to trigger all 5 build workflows on the `lts` branch via `workflow_dispatch` events. This ensures production releases build from the stable `lts` branch code rather than the more frequently updated `main` branch. See [docs/plans/2026-03-02-fix-lts-tag-publishing.md](https://github.com/ublue-os/bluefin/blob/main/docs/plans/2026-03-02-fix-lts-tag-publishing.md) for complete implementation details.
+The dispatcher pattern solves a GitHub Actions constraint where scheduled triggers always execute on the default branch. The `scheduled-lts-release.yml` workflow runs on `main` with `schedule: - cron: '0 2 * * 0'` (weekly on Sunday at 2 AM UTC) and uses GitHub CLI commands (`gh workflow run [workflow].yml --ref lts -R ${{ github.repository }}`) to trigger all 5 build workflows on the `lts` branch via `workflow_dispatch` events. The workflow also includes `workflow_dispatch:` trigger to allow manual execution for on-demand production releases. This ensures production releases build from the stable `lts` branch code rather than the more frequently updated `main` branch. See [docs/plans/2026-03-02-fix-lts-tag-publishing.md](https://github.com/ublue-os/bluefin/blob/main/docs/plans/2026-03-02-fix-lts-tag-publishing.md) for complete implementation details.
 
 **Branch Management and Promotion Strategy:**
 
 The system implements a three-layer defense strategy to protect the `lts` production branch from accidental pollution:
 
-**Layer 1: Manual Promotion Workflow** - A manual `promote-to-lts.yml` workflow enables explicit promotion of tested changes from `main` to `lts`. The workflow:
+**Layer 1: Manual Promotion Workflow** - The `promote-to-lts.yml` workflow enables explicit promotion of tested changes from `main` to `lts`. The workflow:
 - Requires manual trigger via GitHub Actions UI (`workflow_dispatch`)
-- Uses `gh pr create --base lts --head main` to directly create promotion PRs without intermediate branches
-- Opens pull request with documentation warning against reverse merges
+- Creates pull requests directly from `main` → `lts` using `gh pr create --base lts --head main`
+- Includes customizable PR title (default: "Promote main to lts") and body warning against reverse merges
+- Adds `promotion` label to PRs for easy identification
 - Requires operator review and approval before merging
 - Only requires `pull-requests: write` and `issues: write` permissions (no `contents: write` needed)
-- Replaces the previous automatic Pull app (`.github/pull.yml` has been deleted)
+- Replaces the previous automatic Pull app (`.github/pull.yml` was deleted in PR #1159)
 
 **Layer 2: Renovate Restriction** - Renovate configuration restricts dependency updates to target only the `main` branch via `baseBranchPatterns: ["main"]`. This prevents automated dependency PRs from targeting the `lts` branch, ensuring the production branch receives updates only through manual promotion.
 
@@ -108,7 +109,7 @@
 - ❌ Skipped on pull requests to any branch
 - ❌ Skipped on validation builds (push events to `lts` branch that don't publish)
 
-The `sbom:` input parameter has been removed from `reusable-build-image.yml`. SBOM behavior is controlled entirely by step-level conditions checking the branch reference and publish status. The workflow defaults `publish` to `false` for safety—callers must explicitly opt in to publishing.
+SBOM behavior is controlled entirely by step-level conditions (`if: ${{ github.ref == 'refs/heads/lts' && inputs.publish }}`) checking the branch reference and publish status. The workflow defaults `publish` to `false` for safety—callers must explicitly opt in to publishing.
 
 For LTS production releases, SBOMs are generated weekly through the dispatcher pattern. The ublue-os/main repository has SBOM generation disabled but implementation preserved.
 

[Accept] [Decline]

Note: You must be authenticated to accept/decline updates.

How did I do? Any feedback?  Join Discord

castrojo added a commit that referenced this pull request Mar 3, 2026
## Summary

- Brings `lts` CI workflows in sync with `main` using a single direct
commit — no merge, no history pollution
- Fixes the build failures that occurred after PR #1153 merged (Push
Manifest / sign job running when `publish=false`)

## Changes

- Remove `schedule:` from all 5 caller workflows (owned exclusively by
`scheduled-lts-release.yml`)
- Gate `Push Manifest` and `sign` job on `inputs.publish` instead of
`event != pull_request`
- Change `publish` default from `true` to `false`
- Remove `sbom:` input; SBOM steps now gated on `github.ref ==
refs/heads/lts && inputs.publish`
- Add `continue-on-error: true` to all 3 SBOM steps
- Fix `generate-release.yml` to only fire on
`workflow_dispatch`-triggered builds
- Simplify `promote-to-lts.yml` to use `gh pr create --head main` (no
intermediate branch needed)
- Delete `docs/plans/` directory
- Update `AGENTS.md` with authoritative CI architecture documentation

## Why direct file update instead of merge

Previous attempts (PRs #1159, #1160) used merge commits which dragged
polluted history from old pull-bot merges into `lts`. This PR uses `git
checkout origin/main -- <files>` to update files directly, resulting in
a single clean commit with no history contamination.

## After merging

Validation builds (`push` to `lts`, `publish=false`) will run on all 5
variants and should pass cleanly.

Assisted-by: Claude Sonnet 4.5 via OpenCode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/github-action Anything having to do with GHA and automation promotion This PR is a candidate to promote to `lts`. size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant