fix(ci): align scheduled release cron with ublue-os/bluefin (Tuesday 1 AM UTC)#1180
fix(ci): align scheduled release cron with ublue-os/bluefin (Tuesday 1 AM UTC)#1180castrojo wants to merge 3 commits intoublue-os:mainfrom
Conversation
- Replace gh pr create approach with direct squash merge push - Add pre-flight check: fail if lts has commits not in main - Use git merge --squash + single commit to keep lts history linear - No merge commits means no embedded cross-branch history pollution - workflow_dispatch trigger remains as the human approval gate - Add NEVER commit directly to lts rule to AGENTS.md - Update promote-to-lts.yml workflow description in AGENTS.md The previous PR-based approach created merge commits that embedded main's full history (including old circular lts→main references from ffa30fe) into lts on every promotion. Each promotion deepened the diamond graph. Squash merge creates one flat commit per promotion. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Guard commit/push steps on has_changes output to avoid 'nothing to commit' failure when main is already fully merged into lts - Fix promote-to-lts.yml table row in AGENTS.md workflow roles table Addresses Copilot review feedback on PR ublue-os#1177. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…1 AM UTC) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Related Documentation 3 document(s) may need updating based on files changed in this PR: bluefin Bluefin OSView Suggested Changes@@ -110,7 +110,7 @@
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 automatic squash pushes from promotion) 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 automatic squash pushes from promotion) for production releases. Weekly scheduled builds (Tuesdays at 1 AM UTC) are centralized through a dispatcher workflow (`scheduled-lts-release.yml`), with individual workflow `schedule:` triggers removed to prevent duplicate builds
**Dependency Management:**
@@ -182,7 +182,7 @@
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 automatic squash pushes from promotion) 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
+- **lts branch**: Builds triggered by push events (including automatic squash pushes from promotion) for production releases. Weekly scheduled builds (Tuesdays at 1 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.
Kernel Version ManagementView Suggested Changes@@ -6,7 +6,7 @@
The kernel management strategy differs significantly between release streams: [gts and stable streams use the coreos-stable flavor coordinated with Fedora CoreOS](https://github.com/ublue-os/bluefin/blob/c22e0cac0740d478c8c8d009f7a4e54250a9e3e5/Justfile#L116-L125), tracking kernels that arrive approximately [two weeks after landing in Fedora](https://github.com/ublue-os/bluefin/discussions/2709#discussioncomment-13605116), while [latest and beta streams use the main flavor with unpinned latest Fedora kernels](https://github.com/ublue-os/bluefin/blob/c22e0cac0740d478c8c8d009f7a4e54250a9e3e5/Justfile#L116-L125). [Kernel packages are persistently pinned using dnf5 versionlock](https://github.com/ublue-os/bluefin/blob/c22e0cac0740d478c8c8d009f7a4e54250a9e3e5/build_files/base/03-install-kernel-akmods.sh#L34) to maintain compatibility with pre-compiled kernel modules for NVIDIA drivers, ZFS, and other out-of-tree components.
-Bluefin LTS extends this model with [two kernel options: the standard lts tag uses the CentOS 6.12 kernel, while lts-hwe uses the CoreOS kernel with hardware enablement](https://app.dosu.dev/documents/317cf1da-6dda-45d0-bad4-5645878ac451). [Automated weekly releases occur on Sundays at 2 AM UTC](https://github.com/ublue-os/bluefin-lts/pull/1138), [managed through a centralized dispatcher workflow](https://github.com/ublue-os/bluefin-lts/pull/1147) that prevents accidental production releases from automated dependency updates.
+Bluefin LTS extends this model with [two kernel options: the standard lts tag uses the CentOS 6.12 kernel, while lts-hwe uses the CoreOS kernel with hardware enablement](https://app.dosu.dev/documents/317cf1da-6dda-45d0-bad4-5645878ac451). [Automated weekly releases occur on Tuesdays at 1 AM UTC](https://github.com/ublue-os/bluefin-lts/pull/1138), [managed through a centralized dispatcher workflow](https://github.com/ublue-os/bluefin-lts/pull/1147) that prevents accidental production releases from automated dependency updates.
## Release Streams and Kernel Coordination
@@ -178,7 +178,7 @@
**Scheduling Architecture:**
-[All five build workflows use the cron schedule `'0 2 * * 0'` (Sunday 2 AM UTC)](https://github.com/ublue-os/bluefin-lts/pull/1138):
+[All five build workflows use the cron schedule `'0 1 * * TUE'` (Tuesday 1 AM UTC)](https://github.com/ublue-os/bluefin-lts/pull/1138):
- build-regular.yml
- build-dx.yml
- build-gdx.ymlUniversal Blue Build and Update SystemView Suggested Changes@@ -2,7 +2,7 @@
The Universal Blue Build and Update System is the [comprehensive infrastructure encompassing GitHub Actions CI/CD pipelines, OCI container delivery, and multi-layered automatic update architecture](https://app.dosu.dev/documents/5d3b60e6-851d-48a7-9da7-7e6774023def) that powers [Universal Blue](https://universal-blue.org/) and its desktop variants including [Bluefin](https://projectbluefin.io/) and [Aurora](https://getaurora.dev). This system represents a distinct technical area separate from both the Universal Blue platform and the underlying rpm-ostree/bootc tooling, providing project-specific build orchestration and update mechanisms.
-The infrastructure consists of three integrated components: (1) a [GitHub Actions-based CI/CD pipeline that triggers builds on every main branch commit](https://app.dosu.dev/documents/5d3b60e6-851d-48a7-9da7-7e6774023def), with lts branch builds triggered exclusively via a dispatcher workflow that runs weekly (Tuesday 6 AM UTC / 1 AM EST / 2 AM EDT) or manual dispatch, typically delivering changes within 30 minutes to 2 hours; (2) OCI container-based delivery where [operating systems are delivered as complete container images](https://docs.projectbluefin.io/administration/) published to ghcr.io; and (3) a [three-layer update architecture combining bootc for system updates, Flatpak for GUI applications, and Homebrew for CLI tools](https://app.dosu.dev/documents/5d3b60e6-851d-48a7-9da7-7e6774023def). The system implements [intelligent build triggers using digest-based version tracking](https://github.com/ublue-os/main/blob/5ef6bb2adf95dd36b4d428e643a88ad510b7b988/.github/workflows/reusable-build.yml#L74-L107), comprehensive validation including secure boot verification, and advanced optimizations like rechunking for efficient delta updates.
+The infrastructure consists of three integrated components: (1) a [GitHub Actions-based CI/CD pipeline that triggers builds on every main branch commit](https://app.dosu.dev/documents/5d3b60e6-851d-48a7-9da7-7e6774023def), with lts branch builds triggered exclusively via a dispatcher workflow that runs weekly (Tuesday 1 AM UTC) or manual dispatch, typically delivering changes within 30 minutes to 2 hours; (2) OCI container-based delivery where [operating systems are delivered as complete container images](https://docs.projectbluefin.io/administration/) published to ghcr.io; and (3) a [three-layer update architecture combining bootc for system updates, Flatpak for GUI applications, and Homebrew for CLI tools](https://app.dosu.dev/documents/5d3b60e6-851d-48a7-9da7-7e6774023def). The system implements [intelligent build triggers using digest-based version tracking](https://github.com/ublue-os/main/blob/5ef6bb2adf95dd36b4d428e643a88ad510b7b988/.github/workflows/reusable-build.yml#L74-L107), comprehensive validation including secure boot verification, and advanced optimizations like rechunking for efficient delta updates.
Built on [Fedora Silverblue and Kinoite foundations](https://docs.projectbluefin.io/introduction/), the system underwent [major architectural refactoring in 2025 from monolithic distributions to modular OCI containers](https://docs.projectbluefin.io/blog/bluefin-2025/), fully embracing [bootc (bootable containers) as the primary upgrade mechanism](https://docs.projectbluefin.io/blog/bluefin-2025/). The architecture ensures [system images remain pristine with no package-based degradation over time](https://app.dosu.dev/documents/5d3b60e6-851d-48a7-9da7-7e6774023def) while enabling users to switch between variants and update streams seamlessly.
@@ -46,7 +46,7 @@
- Manual `workflow_dispatch` triggers
**LTS branch triggers:**
-- A dispatcher workflow (`scheduled-lts-release.yml`) runs weekly on Tuesday at 6 AM UTC (1 AM EST / 2 AM EDT) on the default branch
+- A dispatcher workflow (`scheduled-lts-release.yml`) runs weekly on Tuesday at 1 AM UTC on the default branch
- The dispatcher triggers all 5 build workflows on the `lts` branch via `workflow_dispatch` events
- 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)
@@ -104,7 +104,7 @@
**SBOM generation behavior:**
SBOMs are generated exclusively when `github.ref == 'refs/heads/lts' && inputs.publish` evaluates to true:
-- ✅ Generated when `lts` branch builds are triggered via the dispatcher workflow (weekly on Tuesday at 6 AM UTC / 1 AM EST / 2 AM EDT) or manual workflow dispatch
+- ✅ Generated when `lts` branch builds are triggered via the dispatcher workflow (weekly on Tuesday at 1 AM UTC) or manual workflow dispatch
- ❌ Skipped on all `main` branch builds (including testing builds)
- ❌ Skipped on pull requests to any branch
- ❌ Skipped on validation builds (push events to `lts` branch that don't publish)
@@ -151,7 +151,7 @@
**Conditional Publishing:**
- The `main` branch publishes images to `:lts-testing` tag on every push commit
- The `lts` branch publishes production tags (`:lts`, `:lts.YYYYMMDD`) only when triggered via `workflow_dispatch` events:
- - Weekly automated releases via the dispatcher workflow (Tuesday 6 AM UTC / 1 AM EST / 2 AM EDT)
+ - Weekly automated releases via the dispatcher workflow (Tuesday 1 AM UTC)
- Manual workflow dispatch for emergency releases
- 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)Note: You must be authenticated to accept/decline updates. |
|
Closing — the Tuesday cron was already included in the squash merge from PR #1177. |
There was a problem hiding this comment.
Pull request overview
Updates the weekly LTS release scheduling to match upstream cadence, and revises the main→lts promotion mechanism/documentation to reflect a squash-push workflow with divergence preflight checks.
Changes:
- Move the scheduled LTS release cron from Sunday 02:00 UTC to Tuesday 01:00 UTC.
- Replace PR-based
main→ltspromotion with a preflight + squash-merge + push workflow. - Update
AGENTS.mdto reflect the new promotion flow (but some schedule references remain outdated).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| AGENTS.md | Documents the updated promotion flow; still contains multiple “Sunday 2am” schedule references that now conflict with the cron change. |
| .github/workflows/scheduled-lts-release.yml | Adjusts the weekly cron to Tuesday 01:00 UTC. |
| .github/workflows/promote-to-lts.yml | Implements preflight divergence check and squash-push promotion to lts (no PR). |
Comments suppressed due to low confidence (1)
AGENTS.md:148
- Phase 2 still documents the dispatcher as firing at
0 2 * * 0(Sunday 2am UTC). With the cron change, this should be updated to Tuesday 1 AM UTC (and keep the cron string consistent with the workflow file).
**Phase 2 — Production release (automated or manual publishing):**
1. `scheduled-lts-release.yml` fires at `0 2 * * 0` (Sunday 2am UTC), OR a maintainer manually triggers it
2. It dispatches all 5 build workflows via `gh workflow run --ref lts`
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| schedule: | ||
| - cron: '0 2 * * 0' # Weekly on Sunday at 2 AM UTC | ||
| - cron: '0 1 * * TUE' # Weekly on Tuesday at 1 AM UTC (matches ublue-os/bluefin) | ||
| workflow_dispatch: # Allow manual triggering |
There was a problem hiding this comment.
The PR title/description indicates only a scheduled-release cron alignment, but this PR also materially changes the promote-to-lts.yml workflow behavior (PR-based promotion → squash-push). Either update the PR description to reflect the additional scope or split the promotion change into a separate PR so reviewers understand the intent and risk.
| - name: Pre-flight check | ||
| run: | | ||
| gh pr create \ | ||
| --repo ${{ github.repository }} \ | ||
| --base lts \ | ||
| --head main \ | ||
| --title "${{ inputs.pr_title }}" \ | ||
| --body "${{ inputs.pr_body }}" \ | ||
| --label "promotion" | ||
| UNIQUE=$(git rev-list origin/lts ^origin/main --count) | ||
| if [ "$UNIQUE" -gt 0 ]; then | ||
| echo "ERROR: lts has $UNIQUE commit(s) that are not in main:" | ||
| git log --oneline origin/lts ^origin/main | ||
| echo "" | ||
| echo "All changes must land in main before promoting to lts." | ||
| echo "Land the above commits in main first, then re-run this workflow." | ||
| exit 1 | ||
| fi | ||
| echo "Pre-flight passed: lts has no commits outside of main." | ||
|
|
There was a problem hiding this comment.
The pre-flight check can incorrectly report success if git rev-list fails (e.g., if the expected remote refs aren’t present), because the script doesn’t set -e and an empty/non-numeric $UNIQUE will cause [ ... -gt 0 ] to error and be treated as “false”. Add strict shell settings (at least set -euo pipefail) and/or explicitly validate $UNIQUE before comparing so the workflow fails closed.
| run: | | ||
| git commit \ | ||
| -m "${{ inputs.commit_title }}" \ | ||
| -m "${{ inputs.commit_body }}" |
There was a problem hiding this comment.
Avoid embedding ${{ inputs.* }} directly into the shell command line for git commit. GitHub interpolates these before the shell runs, so special characters/newlines can lead to surprising parsing, and patterns like $(...)/backticks in the input would be executed by the shell. Pass inputs via env: and reference them as normal shell variables (quoted) to prevent command injection and make message handling robust.
| run: | | |
| git commit \ | |
| -m "${{ inputs.commit_title }}" \ | |
| -m "${{ inputs.commit_body }}" | |
| env: | |
| COMMIT_TITLE: ${{ inputs.commit_title }} | |
| COMMIT_BODY: ${{ inputs.commit_body }} | |
| run: | | |
| git commit \ | |
| -m "$COMMIT_TITLE" \ | |
| -m "$COMMIT_BODY" |
| @@ -121,7 +121,7 @@ This section is the authoritative reference for all CI/CD behavior. Read it comp | |||
| | `build-dx-hwe.yml` | Caller — builds `bluefin-dx` with HWE kernel | | |||
| | `reusable-build-image.yml` | Reusable workflow — all 5 callers invoke this | | |||
| | `scheduled-lts-release.yml` | Dispatcher — owns the weekly Sunday production release | | |||
There was a problem hiding this comment.
scheduled-lts-release.yml is now Tuesday, but this table row still says it “owns the weekly Sunday production release”. Update the wording to match the new Tuesday 1 AM UTC schedule so this doc remains authoritative.
| | `scheduled-lts-release.yml` | Dispatcher — owns the weekly Sunday production release | | |
| | `scheduled-lts-release.yml` | Dispatcher — runs the weekly Tuesday 1 AM UTC production release | |
| - `scheduled-lts-release.yml` — Weekly production release dispatcher (sole owner of Sunday builds) | ||
| - `promote-to-lts.yml` — Opens a one-way `main` → `lts` promotion PR | ||
| - `promote-to-lts.yml` — Squash-pushes `main` into `lts` (with pre-flight divergence check) |
There was a problem hiding this comment.
This list item still says scheduled-lts-release.yml is the “sole owner of Sunday builds”. Since the cron is now Tuesday 1 AM UTC, update this wording (and any nearby “Sunday” references in the same section) to avoid conflicting guidance.
Changes
scheduled-lts-release.ymlcron from0 2 * * 0(Sunday 2 AM) to0 1 * * TUE(Tuesday 1 AM UTC) to match the release cadence of ublue-os/bluefin.