Skip to content

Apply template updates as migrations in sync PRs - #4520

Draft
Skitionek wants to merge 6 commits into
nf-core:devfrom
Skitionek:feat-sync-template-migrations
Draft

Skitionek wants to merge 6 commits into
nf-core:devfrom
Skitionek:feat-sync-template-migrations

Conversation

@Skitionek

Copy link
Copy Markdown

PR checklist

  • This comment contains a description of changes (with reason)
  • CHANGELOG.md is updated (PR number still to fill in)
  • If you've fixed a bug or added code that should be tested, add tests!

What

nf-core pipelines sync --template-migrations clean applies the template update to dev change by change, and when every change applies, the PR branch becomes a merge commit of dev and the new TEMPLATE commit, so the template PR opens with no merge conflicts. The sync workflow passes clean for nf-core-bot PRs; the option is off by default for local runs.

The PR description gets a report either way: changes that conflict, each with its template diff, and the remaining nf-core steps (module and subworkflow updates, RO-Crate, container configs) as a checklist. When a change conflicts, the PR stays the plain template merge it is today.

Why

git's merge conflicts wherever a pipeline diverged from the template, often only because a neighbouring line was edited. Here each template change is applied with the least context that keeps it unique, nf-core modules are compared through modules.json instead of patched, and files nf-core generates are left to its own commands.

Decision

Migrations are generated during sync from the TEMPLATE commit dev last merged to the new one, so each pipeline gets its own render (including skip_features) and no migration has to be written per tools release. A partial mode also pushes when some changes conflict, leaving those files untouched; the workflow uses clean because a pushed merge marks the template as merged, so changes left out would survive only in the PR description.

Not in this PR

  • A pipeline whose dev merged a template update and then reverted it (as nf-core/spatialaxe did with 4.0.2) still gets those conflicts, because git history says that template is merged.
  • 24 of the 28 tests in tests/pipelines/test_sync.py already fail on dev locally: test pipelines start dirty because prettier fixes a double space in the template's branch.yml after the first commit. That needs its own fix; the new tests build their own git fixtures.

Replaying nf-core/atacseq's 4.0.2 → 4.0.3 sync gives the merge its maintainers made, apart from their CHANGELOG entry and the RO-Crate, which the report lists as a manual step. The approach is ported from Skitionek/nf-migrate, whose validation replays 43 template merges from 11 pipelines.


Coding and writing assisted with Claude Opus 5.5

@codecov

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.21%. Comparing base (354127e) to head (ae96ab7).

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codspeed

codspeed Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 9 untouched benchmarks


Comparing Skitionek:feat-sync-template-migrations (ae96ab7) with dev (354127e)

Open in CodSpeed

Skitionek added a commit to Skitionek/tools that referenced this pull request Oct 15, 2026
Coverage on nf-core#4520 pointed at three branches that cannot run.
SequenceMatcher alternates equal and changed opcodes, so the block next
to a change is always equal. The hold-back runs on a fresh workspace, so
its snapshot is always empty and dropping the pending changes is enough.
git only lists a changed file that one of the two commits has, so the
"missing on both sides" case becomes an assert.

Coding assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Fix the coverage reported on the PR."
Skitionek added a commit to Skitionek/tools that referenced this pull request Oct 15, 2026
Covers the remaining branches Codecov reported on nf-core#4520: hunks that grow
into or merge with a neighbouring change (inputs found by searching
small texts, checked by applying the hunks), an empty template file, a
template without .nf-core.yml, module files missing from modules.json, a
pipeline without modules.json, the version line helpers, a branch with
no template history, and the PR text for conflicting and partial
migrations. The sync tests also pin that migrations run after the merge
branch is created and before it is pushed.

Coding assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Fix the coverage reported on the PR."
A template sync PR merges the new TEMPLATE commit into dev, and git's
merge conflicts wherever the pipeline diverged from the template. These
operations are the building blocks for applying a template update
change by change instead: each inspects the pipeline first and reports
applied, already applied, or conflict, so running it twice is safe and
nothing is placed where it does not fit.

nf-core modules and subworkflows are compared through modules.json and
reported with the nf-core command to run, since pipelines often update
them past the template's pinned version. Files nf-core generates become
manual steps. Changes are held in memory until committed, so a conflict
can be dropped without touching the pipeline.

Ported from Skitionek/nf-migrate (32a6908, 2deb945), without that
tool's per-pipeline placeholders: in sync, both template renders already
carry the pipeline's own values.

Coding assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Check out nf-core/tools, create a branch, port the commits from Skitionek/nf-migrate, and adapt them to run as part of the template update PRs that nf-core-bot opens."
The difference between two TEMPLATE commits is the template update. It
is turned into operations that can be applied to a pipeline that has
diverged from the template: each change keeps only as much context as
it needs to be unique, and a replacement whose changed lines are unique
keeps none, so an edit to a neighbouring line cannot block it.

nf-core modules and subworkflows become component checks, since
pipelines manage them with `nf-core modules`. The RO-Crate and container
configs, which nf-core regenerates, and binary files become manual
steps naming the command to run. The nf_core_version line is left out of
the diff and stamped separately.

Ported from Skitionek/nf-migrate (32a6908, 12804dc), generating
operations directly rather than migration source files.

Coding assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Check out nf-core/tools, create a branch, port the commits from Skitionek/nf-migrate, and adapt them to run as part of the template update PRs that nf-core-bot opens."
The template changes between the TEMPLATE commit a branch last merged
and a new one are applied to that branch in a temporary worktree, and
the result is recorded as a merge commit of the branch and the new
TEMPLATE commit. Using the merge base rather than the previous TEMPLATE
commit means a pipeline that skipped a sync still gets every change it
lacks, as a git merge would.

A conflict means no commit by default. With allow_conflicts the commit
holds every change that fits; a file with any conflicting change is left
as it was, because applying only some of a file's changes can leave it
half converted. The report lists conflicts with the template change as
a collapsed diff, and manual steps as a checklist.

Ported from Skitionek/nf-migrate (b9f8773, 2deb945), applying one
generated step instead of a chain of versioned migrations.

Coding assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Check out nf-core/tools, create a branch, port the commits from Skitionek/nf-migrate, and adapt them to run as part of the template update PRs that nf-core-bot opens."
`nf-core pipelines sync --template-migrations` applies the template
update to --from-branch change by change, after the merge branch is
created from the new TEMPLATE commit. With `clean`, when every change
applies, the merge branch moves to a merge commit of the pipeline branch
and the template, so the PR opens without merge conflicts. With
`partial`, it also moves when some changes conflict, keeping the
changes that fit and leaving files with a conflicting change as they
were. Otherwise the branch stays on the template commit, as before.

The PR description gets a report of what happened, the conflicting
changes with their template diff, and the remaining nf-core steps
(module updates, RO-Crate and container configs) as a checklist. The
option is off by default; the sync workflow passes `clean` for
nf-core-bot PRs and lets a dispatch choose another mode.

Replaces the GitHub Action of Skitionek/nf-migrate (b9f8773): the work
happens while sync opens the PR instead of in a workflow reacting to it.

Coding and writing assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Check out nf-core/tools, create a branch, port the commits from Skitionek/nf-migrate, and adapt them to run as part of the template update PRs that nf-core-bot opens."
Coverage on nf-core#4520 pointed at three branches that cannot run.
SequenceMatcher alternates equal and changed opcodes, so the block next
to a change is always equal. The hold-back runs on a fresh workspace, so
its snapshot is always empty and dropping the pending changes is enough.
git only lists a changed file that one of the two commits has, so the
"missing on both sides" case becomes an assert.

Coding assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Fix the coverage reported on the PR."
Covers the remaining branches Codecov reported on nf-core#4520: hunks that grow
into or merge with a neighbouring change (inputs found by searching
small texts, checked by applying the hunks), an empty template file, a
template without .nf-core.yml, module files missing from modules.json, a
pipeline without modules.json, the version line helpers, a branch with
no template history, and the PR text for conflicting and partial
migrations. The sync tests also pin that migrations run after the merge
branch is created and before it is pushed.

Coding assisted with Claude Opus 5.5

Prompts (edited for grammar, private details removed):
- 2026-10-15: "Fix the coverage reported on the PR."
@Skitionek
Skitionek force-pushed the feat-sync-template-migrations branch from 58843f9 to ae96ab7 Compare October 16, 2026 12:32

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant