Skip to content

Bumping Ebuilds

Fabio Scaccabarozzi edited this page Aug 29, 2026 · 3 revisions

Bumping Ebuilds

scripts/bump_and_qa_ebuild.sh is the tool for moving COSMIC packages to a new cosmic-epoch tag. It discovers packages by directory name (cosmic-*, plus xdg-desktop-portal-cosmic and pop-launcher) under cosmic-base/, so dev-lang/dart and other non-COSMIC toolchain packages are out of scope for it — see Adding and Updating Packages for those.

Requires an authenticated GitHub CLI (gh auth login) and network access to GitHub, unconditionally — even for -n/--dry-run or --no-upload runs. The startup checks (gh in PATH, gh auth status, a live gh api reachability check against COSMIC_OVERLAY_REPO) run before any flag-specific logic and will hard-fail the script if they don't pass. --no-upload only skips the later gh release create/upload calls, not these startup checks.

There is no resume mode. A run without -p reprocesses every discovered package from scratch every time — it does not skip packages a previous run already completed. In practice this means: run it once for the whole set, then use -p <pkg> to retry only the packages that failed (see below), never a bare re-run to "continue".

Basic usage

# Full release bump, all packages
./scripts/bump_and_qa_ebuild.sh -v epoch-1.4.0

# Preview only, no changes written
./scripts/bump_and_qa_ebuild.sh -n epoch-1.4.0

# Single package (also how you retry a package that failed)
./scripts/bump_and_qa_ebuild.sh -v epoch-1.4.0 -p cosmic-comp

-v/--verbose isn't required but is used in practice on every invocation — the default log level is too quiet to debug a failure after the fact.

-p/--package only accepts one package per invocation — passing it twice silently keeps only the last one, it does not process both. For a handful of specific packages, just invoke the script once per package.

Other flags:

  • -r<N> / --revision <N> — Gentoo revision bump (-r1, ...), for overlay-only patch bumps (see Release Workflow notes on versioning)
  • --no-commit — run the pipeline without committing, to inspect the result first
  • --no-upload — skip the GitHub release/tarball upload step (local-only testing)
  • --allow-non-frozen-vendoring — run cargo vendor without --locked; needed when upstream forgot to bump Cargo.lock for a tag (requires -p, one package)
  • -c/--create <pkg> --description <text> — bootstrap a brand-new package (see Adding and Updating Packages)
  • --clean-temp — delete the kept temp working directory for this version when the run finishes (see "Temp directories" below)

Environment variables COSMIC_EPOCH_REPO, COSMIC_OVERLAY_REPO, DISTDIR override the upstream repo, this overlay's GitHub repo (for release uploads — set this if you're running the script against a fork), and the portage distfiles dir, respectively. They can also be set persistently in ~/.cosmic-bump.conf (sourced before CLI args are parsed, so CLI flags still win). ./scripts/bump_and_qa_ebuild.sh --help prints the full reference including examples.

What it does per package

Nine phases, run in order, for each package:

  1. Archive — build a unified source+vendored-crates tarball from the cosmic-epoch submodule (cargo vendor --locked unless --allow-non-frozen-vendoring). Skipped for meta-packages (no Cargo.toml/Makefile/justfile/src/).
  2. Manifest write — write the DIST entry (BLAKE2B+SHA512) for that tarball into Manifest. The script's own hashes are authoritative — it does not shell out to ebuild digest.
  3. Upload — push the tarball to a GitHub release tagged ${GENTOO_VERSION} in COSMIC_OVERLAY_REPO (creating the release if needed). Skipped with --no-upload or -n.
  4. Bump — generate the new ebuild by copying the highest-versioned existing tagged ebuild in the package directory (via sort -V, -9999 excluded) and updating only the VERGEN_GIT_COMMIT_DATE/VERGEN_GIT_SHA variables if present. Nothing else in the ebuild is touched automatically.
  5. Verify fetchebuild <pkg>-<version>.ebuild fetch, to prove the Manifest hashes just written actually resolve.
  6. Sysdeps check — cross-references vendored -sys crates against a built-in crate→Gentoo-package map and warns about anything unmapped. Non-fatal: recorded in the report, never blocks the package or fails the run. Dependencies are never added to the ebuild automatically.
  7. src_prepare testebuild <pkg>-<version>.ebuild clean unpack prepare. On failure, if the ebuild has a PATCHES= entry, the script comments the whole block out and retries once (see Troubleshooting); if that also fails, or there's no PATCHES entry, the package fails here.
  8. QA scanpkgcheck scan cosmic-base/<pkg> (default pkgcheck settings, not scripts/pkgcheck.conf — see QA and Testing). Non-fatal: any output is recorded in the report but never blocks the commit.
  9. Commitgit add the ebuild (+ Manifest, unless meta-package) and commit as cosmic-base/<pkg>: add <version>, with a note appended if PATCHES was commented or sysdeps were missing. Skipped with --no-commit or -n.

Meta-packages (cosmic-meta, pop-theme-meta) only go through phases 4, 8, 9 — no source, so no tarball/fetch/prepare.

Because step 4 is a straight copy of the previous tagged ebuild, the automation does not know about anything upstream changed — a new install path in the Justfile, a new system dependency in Cargo.toml, a renamed binary. That's exactly what step 5 of Release Workflow (checking upstream release notes/diffs) exists to catch; the script will happily produce a bumped ebuild that builds and installs the old file layout against the new source.

Failures don't stop the run

If a package fails phase 1–5 or 7, the script logs it to the run's failure list and moves on to the next package rather than aborting — a full run against ~35 packages will get through the rest even if several need manual attention. Phases 6 and 8 (sysdeps, QA) never fail a package at all.

For phases 4, 5, and 7 specifically, a failure automatically rolls back what that package's run had touched: the Manifest entry is restored and the half-written <pkg>-<version>.ebuild is deleted before the script moves to the next package. You generally don't need to manually git rm/rm anything before retrying — just fix the underlying problem and re-run with -p <pkg>.

Reading a run

There's no persisted state — the completed/failed/patches-commented/missing-deps/QA-issues report is generated in memory at the end of that one run and printed to both the console and the timestamped log file (.bump-<version>-<timestamp>.log, auto-.gitignored). If you need to check what happened in a run you're not looking at anymore, read that log file — there's no separate state file to consult (despite .gitignore still listing a .bump-state-*.json pattern, a leftover from an older version of the script).

To find the actual error quickly instead of scrolling:

grep -i -e rror -e failed .bump-<version>-<timestamp>.log

When a package fails the automated bump

  1. Reproduce interactively from inside the package directory — this mirrors what phase 7 does, plus the compile/install the script doesn't test:
    cd cosmic-base/<pkg>
    ebuild <pkg>-<version>.ebuild clean unpack prepare   # what phase 7 runs
    ebuild <pkg>-<version>.ebuild compile
    ebuild <pkg>-<version>.ebuild install
    ebuild <pkg>-<version>.ebuild clean                  # always clean up the work dir after
  2. Diff against the previous tagged ebuild (the template phase 4 copied from) and against -9999, since -9999 is the only place upstream/eclass changes might already be reflected:
    diff -Nuar <pkg>-<prev-version>.ebuild <pkg>-<version>.ebuild
    diff -Nuar <pkg>-<version>.ebuild <pkg>-9999.ebuild
    A recurring cause: an eclass function/variable was renamed (e.g. cosmic-de-r2_target_dircosmic-common_target_dir) and the copied ebuild still references the old name. Fix with a targeted sed across affected ebuilds if it's systemic:
    sed -i -e 's:cosmic-de-r2_target_dir:cosmic-common_target_dir:' */*/*-<version>.ebuild
  3. If you generated a replacement vendor tarball out-of-band, append its DIST line manually rather than hand-computing hashes — b2sum/sha512sum produce them:
    DIST <pkg>-<version>.tar.zst BLAKE2B <hash> SHA512 <hash>
    
  4. Re-run the script for just that package once the fix is in place:
    ./scripts/bump_and_qa_ebuild.sh -v epoch-1.4.0 -p <pkg>

Manual patches / backports

For a fix that needs to ship as an ebuild-level patch rather than waiting for upstream to retag:

ebuild <pkg>-<version>.ebuild prepare        # unpacks to a work dir
diff -Nuar <pkg>-<version>.orig <pkg>-<version> \
  > cosmic-base/<pkg>/files/<pkg>-<version>-backport-<PR#>.patch

Reference the new patch file from PATCHES=() in the ebuild. Name patches descriptively (-backport-137.patch for "backports upstream PR #137") so a future reader knows why it exists without archaeology.

If phase 7 comments out a PATCHES entry because it failed to apply (see phase list above), that's a signal the patch needs regenerating against the new source. The comment-out is only there to let the rest of the bump proceed — it always surfaces the package as PATCHES COMMENTED in the run report and in the commit message; regenerating or re-enabling the patch is a manual follow-up, never attempted automatically.

Temp directories

By default the script keeps its per-run temp working directory (under TMPDIR, /var/tmp unless overridden — deliberately not /tmp, to avoid running out of space on a tmpfs-backed mount) after finishing, purely so you can inspect it if something looked off. Clean it up when you're done:

./scripts/bump_and_qa_ebuild.sh epoch-<version> --clean-temp
# or, if you already know the run is over and want it gone now:
rm -rf /var/tmp/cosmic-bump.*

Post-bump sanity checks

After a batch of bumps, before committing the "drop old version" cleanup (see Release Workflow):

pkgcheck scan --config scripts/pkgcheck.conf
python3 scripts/simple-qa-check.py
emerge -uDN @world --quiet --keep-going

The emerge run is what actually proves the bumped packages build and install — see QA and Testing for why a pkgcheck scan alone isn't sufficient proof.

Clone this wiki locally