Skip to content
Closed
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
31 changes: 16 additions & 15 deletions .automation/skills/upstream-rebase/SKILL.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 -- <files the fix touched>
Expand Down
5 changes: 3 additions & 2 deletions .github/scripts/tests/verify-upstream-rebase.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/automation-selftest.yml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
37 changes: 31 additions & 6 deletions .github/workflows/kernel-nightly.yml
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
17 changes: 11 additions & 6 deletions .github/workflows/rebase-land.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/<tree>/... 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
Expand All @@ -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:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/upstream-rebase.yml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading