diff --git a/.automation/skills/upstream-rebase/SKILL.md b/.automation/skills/upstream-rebase/SKILL.md index c23286bb72c4a9..ea62a15c6628bf 100644 --- a/.automation/skills/upstream-rebase/SKILL.md +++ b/.automation/skills/upstream-rebase/SKILL.md @@ -1,14 +1,14 @@ --- name: upstream-rebase -description: Nightly rebase of edera/mainline onto torvalds master, run unattended in CI by .github/workflows/upstream-rebase.yml. Covers the replay, conflict resolution, build checks, the audit of upstream fixes that meet the series, and the report the workflow publishes. +description: Nightly rebase of an Edera kernel integration tree (edera/mainline onto torvalds master, edera/6.18-lts onto stable linux-6.18.y), run unattended in CI by .github/workflows/upstream-rebase.yml. Covers the replay, conflict resolution, build checks, the audit of upstream fixes that meet the series, and the report the workflow publishes. --- # Nightly upstream rebase You are rebasing the Edera downstream kernel series (around 80 commits: Hyper-V-nested-on-Xen, the Xen PV-IOMMU, NUMA-aware Xen backends, 2 MiB -ballooning, OpenPaX, and assorted fixes) on `edera/mainline` onto Linus' -tree. The goal is a replay that changes **nothing downstream**: every +ballooning, OpenPaX, and assorted fixes) onto the upstream branch its tree +tracks. The goal is a replay that changes **nothing downstream**: every difference in the final tree must come from the upstream delta alone. Where that is impossible, because upstream and downstream touched the same code, you resolve the conflict the way a careful kernel maintainer would and you say @@ -50,7 +50,8 @@ report is a success; one that hides a judgement call is not. The workflow gives you, in the prompt: -- `DOWNSTREAM`: the branch being rebased, `edera/mainline`. +- `DOWNSTREAM`: the branch being rebased, `edera/mainline` or + `edera/6.18-lts`. - `OLD_TIP`: its current commit (already checked out). - `UPSTREAM`: the upstream commit to rebase onto, fetched as the local branch `upstream-target`. @@ -83,8 +84,8 @@ git rev-list --count --no-merges MB..OLD_TIP # downstream commits git log --oneline --no-merges MB..UPSTREAM # what is new upstream ``` -The upstream range is large (a few days of mainline, far more during a merge -window), so do not read it all. Find where it meets the +The upstream range is large (a stable release, or a few days of mainline, +including merge windows), so do not read it all. Find where it meets the series: ```sh @@ -116,12 +117,12 @@ When a commit conflicts: - Read the upstream change that caused it **and** the downstream commit's intent (its message, and the rest of its diff). Resolve so the downstream commit does what it did before, on top of what upstream now does. -- Upstream wins on fixes. If an upstream fix changed the code a downstream - commit edits, keep every check, lock, ordering constraint and error path - the fix introduced, and fit the downstream change around it. -- If upstream now contains the downstream change itself (it was upstreamed, - perhaps through a subsystem tree), let the downstream commit go empty and - let git drop it. Record that, with the upstream commit. +- Upstream wins on fixes. If a stable backport or a mainline fix changed the + code a downstream commit edits, keep every check, lock, ordering constraint + and error path the fix introduced, and fit the downstream change around it. +- If upstream now contains the downstream change itself (it was upstreamed or + backported to stable), let the downstream commit go empty and let git drop + it. Record that, with the upstream commit. - If you cannot tell what the right resolution is, do not guess silently. Make the most conservative resolution you can defend, mark it **UNSURE** in the report, and explain both readings. @@ -167,9 +168,9 @@ For every upstream commit flagged in step 1, check that its change **survived the replay**. Ancestry is not enough: a downstream commit replayed on top can edit the very lines a fix added. -Give fixes the most attention: anything with a `Fixes:` tag, a `CVE-` -reference, or `Cc: stable`. For each one that touched a file the series also -touches: +Give fixes the most attention: stable commits (every one of them is a fix), +and in mainline anything with a `Fixes:` tag, a `CVE-` reference, or `Cc: +stable`. For each one that touched a file the series also touches: ```sh git log --oneline UPSTREAM..RESULT -- diff --git a/.github/scripts/tests/verify-upstream-rebase.test.sh b/.github/scripts/tests/verify-upstream-rebase.test.sh index a28d96d3ddb624..5aca9d20194045 100755 --- a/.github/scripts/tests/verify-upstream-rebase.test.sh +++ b/.github/scripts/tests/verify-upstream-rebase.test.sh @@ -4,8 +4,9 @@ # Builds a small throwaway repository with an upstream line and a downstream # series on it, rebases the series onto a newer upstream, and then damages # copies of that result in each way the checker exists to catch. The nightly -# rebase force-pushes edera/mainline on this script's say-so, so every -# damaged copy must be refused, and every honest replay must pass. +# rebase force-pushes edera/6.18-lts and edera/mainline on this script's +# say-so, so every damaged copy must be refused, and every honest replay must +# pass. # # Run from anywhere: bash .github/scripts/tests/verify-upstream-rebase.test.sh set -uo pipefail diff --git a/.github/workflows/automation-selftest.yml b/.github/workflows/automation-selftest.yml index fc7305654ec509..5323cf6c6e9025 100644 --- a/.github/workflows/automation-selftest.yml +++ b/.github/workflows/automation-selftest.yml @@ -1,8 +1,8 @@ name: Automation self-test # Tests the scripts the nightly rebase relies on to decide whether to -# force-push edera/mainline, so a change that weakens either must not land -# quietly: +# force-push edera/mainline and edera/6.18-lts, so a change that weakens +# either must not land quietly: # # - verify-upstream-rebase.sh: honest replays pass, including one that # flattens a merged series; edited, dropped, added and merged commits and diff --git a/.github/workflows/kernel-nightly.yml b/.github/workflows/kernel-nightly.yml index 09be7062f90f45..7bcd4a0e3f5089 100644 --- a/.github/workflows/kernel-nightly.yml +++ b/.github/workflows/kernel-nightly.yml @@ -1,19 +1,22 @@ name: Nightly kernel maintenance -# Rebases edera/mainline onto torvalds master every night -# (upstream-rebase.yml). +# Rebases the two Edera kernel integration trees every night, in parallel +# (upstream-rebase.yml, once per tree): # -# Claude does the rebase. Independent checks decide whether the result is +# - edera/mainline onto torvalds master; +# - edera/6.18-lts onto stable linux-6.18.y. +# +# Claude does the rebases. Independent checks decide whether each result is # pushed or proposed as a pull request; see upstream-rebase.yml. # -# GitHub runs scheduled workflows only from the default branch, which is -# edera/6.18-lts. Until this file is there too, the schedule does not fire. +# GitHub runs scheduled workflows only from the default branch, edera/mainline, +# so this copy runs for both trees. # # Repository configuration this needs: # vars.REBASE_APP_CLIENT_ID, secrets.REBASE_APP_PRIVATE_KEY # A GitHub App installed on this repository with contents, pull requests # and workflows write, allowed to bypass the protection rules on -# edera/mainline. GITHUB_TOKEN cannot do this job: it cannot push +# edera/mainline and edera/6.18-lts. GITHUB_TOKEN cannot do this job: it cannot push # commits that touch .github/workflows/ (every rebase rewrites the ones # that add them), and pull requests it opens do not trigger other # workflows. @@ -29,6 +32,11 @@ on: - cron: '23 3 * * *' # 03:23 UTC nightly workflow_dispatch: inputs: + only: + description: Rebase one tree instead of both + type: choice + options: [all, mainline, 6.18-lts] + default: all force: description: Rebase even if an open rebase pull request already covers this upstream tip type: boolean @@ -43,6 +51,7 @@ concurrency: jobs: mainline: + if: inputs.only == '' || inputs.only == 'all' || inputs.only == 'mainline' uses: ./.github/workflows/upstream-rebase.yml permissions: contents: read @@ -56,3 +65,19 @@ jobs: upstream_branch: master force: ${{ inputs.force == true }} secrets: inherit + + lts: + if: inputs.only == '' || inputs.only == 'all' || inputs.only == '6.18-lts' + uses: ./.github/workflows/upstream-rebase.yml + permissions: + contents: read + pull-requests: read + issues: write + id-token: write + with: + downstream: edera/6.18-lts + key: 6.18-lts + upstream_url: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git + upstream_branch: linux-6.18.y + force: ${{ inputs.force == true }} + secrets: inherit diff --git a/.github/workflows/rebase-land.yml b/.github/workflows/rebase-land.yml index ce3e39ff627cd1..f5a1476e923b55 100644 --- a/.github/workflows/rebase-land.yml +++ b/.github/workflows/rebase-land.yml @@ -8,12 +8,13 @@ name: Land upstream rebase # old one. Approving instead force-pushes the tree to the exact commit that # was approved, and GitHub then marks the pull request merged. # -# A review runs this workflow from the pull request's merge ref, which is why -# it lives on edera/mainline. +# A review runs this workflow from the pull request's merge ref, not from the +# default branch, so it only runs for a tree that carries this file. # # What has to hold before anything is pushed: -# - the pull request is a rebase/edera-mainline/... branch from this -# repository, targeting edera/mainline; +# - the pull request is a rebase//... branch from this repository, +# targeting that tree: rebase/edera-mainline/... into edera/mainline, or +# rebase/edera-6.18-lts/... into edera/6.18-lts; # - the review approved the current head, not an earlier one; # - the approver has write access; # - the tree is still the tip the branch was made from. The branch name @@ -40,8 +41,12 @@ jobs: if: >- github.event.review.state == 'approved' && github.event.pull_request.head.repo.full_name == github.repository - && github.event.pull_request.base.ref == 'edera/mainline' - && startsWith(github.event.pull_request.head.ref, 'rebase/edera-mainline/') + && ( + (github.event.pull_request.base.ref == 'edera/mainline' + && startsWith(github.event.pull_request.head.ref, 'rebase/edera-mainline/')) + || (github.event.pull_request.base.ref == 'edera/6.18-lts' + && startsWith(github.event.pull_request.head.ref, 'rebase/edera-6.18-lts/')) + ) runs-on: ubuntu-latest timeout-minutes: 15 permissions: diff --git a/.github/workflows/upstream-rebase.yml b/.github/workflows/upstream-rebase.yml index 75056019338fdf..5e4c650a01a5d8 100644 --- a/.github/workflows/upstream-rebase.yml +++ b/.github/workflows/upstream-rebase.yml @@ -1,7 +1,8 @@ name: Upstream rebase -# Rebases an Edera kernel integration tree onto its upstream. Called nightly -# by kernel-nightly.yml for edera/mainline, onto torvalds master. +# Rebases one Edera kernel integration tree onto its upstream. Called nightly +# by kernel-nightly.yml, once for edera/mainline (onto torvalds master) and +# once for edera/6.18-lts (onto stable linux-6.18.y). # # Claude does the rebase, following .automation/skills/upstream-rebase/ # SKILL.md: it replays the series, resolves conflicts, fixes what the replay