ci: enable matrix-driven multi-variant kernel delivery - #63
Open
Bjordis Collaku (bjordiscollaku) wants to merge 15 commits into
Open
ci: enable matrix-driven multi-variant kernel delivery#63Bjordis Collaku (bjordiscollaku) wants to merge 15 commits into
Bjordis Collaku (bjordiscollaku) wants to merge 15 commits into
Conversation
There was a problem hiding this comment.
zizmor found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
This was referenced Aug 11, 2026
Christopher Obbard (obbardc)
left a comment
There was a problem hiding this comment.
I had a quick look at this (just overall diff), it appears to be in the right kind of shape.
…ipeline
Introduce a fully parameterized CI matrix that supports multiple build
targets, per-target package naming, per-target config fragment selection,
and a dedicated release workflow that promotes packages to a stable
Debusine workspace.
ci/build-matrix.json:
- New schema replaces the flat {distro} list. Each row carries: type
(Daily|Release), target_workspace, suites (array -- flattened by
resolve-matrix.sh), git_clone, branch_or_tag, srcpkg, binpkg,
kernel_config, debian_revision.
- M1 rows: Daily (latest qcom-next tag, trixie+forky) and Release
(pinned qcom-next-7.2-rc3-20260722, trixie+forky).
ci/scripts/ (new directory, CI orchestration only):
- resolve-matrix.sh: reads build-matrix.json, filters by --type, expands
suites arrays into one flat entry per suite, emits compact JSON to stdout.
Accepts --single-suite for manual dispatch single-target overrides.
Called by both daily.yml and release.yml.
- resolve-kernel-ref.sh: resolves the kernel ref to build. --latest mode
queries the remote for the newest qcom-next-*-YYYYMMDD tag using date-
based sort (not version sort). --ref mode is a validated passthrough for
pinned release builds. Extracted from the inline pipeline in build-kernel-
deb.yml where it was fragile and untestable.
- derive-localversion.sh: derives the LOCALVERSION suffix from a kernel ref.
Tag pattern (qcom-next-<kver>-<YYYYMMDD>) produces -<prefix>-<date>.
Branch-tip (no date) produces -<ref>-g<short_sha> and requires --sha.
Extracted from the inline sed pipeline in build-kernel-deb.yml.
daily.yml:
- configure-matrix job delegates to ci/scripts/resolve-matrix.sh --type Daily
instead of the previous jq pass-through. Handles full matrix (schedule or
run-full-matrix) and single-suite manual dispatch.
- build job threads all new matrix fields (suite, srcpkg, binpkg,
kernel-config, debian-revision, git-clone) to build-kernel-deb.yml.
- suite choices updated to include forky.
- Does NOT pass target-workspace (daily builds use the S3 publish path).
release.yml (new):
- workflow_dispatch only, no schedule trigger.
- configure-matrix delegates to resolve-matrix.sh --type Release.
- build job passes latest-tag=false and kernel-branch from the pinned
branch_or_tag field, plus target-workspace to trigger the Debusine
release path in build-kernel-debusine.yml.
build-kernel-deb.yml:
- New inputs: suite (replaces distro), git-clone, srcpkg, binpkg,
kernel-config, debian-revision, target-workspace.
- Resolve kernel ref and derive LOCALVERSION are now thin wrappers around
ci/scripts/resolve-kernel-ref.sh and ci/scripts/derive-localversion.sh.
- prepare-source.sh invocation passes --srcpkg, --binpkg, --debian-revision,
--kernel-config through to the packaging branch.
- debusine-build job passes srcpkg and target-workspace to
build-kernel-debusine.yml.
- forky added to workflow_dispatch suite choices.
build-kernel-debusine.yml:
- New inputs: srcpkg, target-workspace.
- build job exposes srcpkg_version as a job output (from generate-source-
package step) for use by the release job.
- publish job (S3): runs only when target-workspace is empty (daily path).
- release job (new): runs only when target-workspace is non-empty. Calls
debusine-action/lib/release to promote packages from the ephemeral CI
workspace to the stable target workspace. Uses DEBUSINE_RELEASE_TOKEN
(separate secret with release permissions).
Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
The prepare job checks out the packaging branch (qcom/debian/latest) as its working directory, which does not contain ci/scripts/. The Resolve kernel ref and Derive LOCALVERSION steps call ci/scripts/resolve-kernel- ref.sh and ci/scripts/derive-localversion.sh respectively, causing a 'No such file or directory' failure. Fix: add two steps after the packaging branch checkout that sparse-check out the CI branch (github.sha, always the main/feature branch that owns the workflows) into a temporary .ci-branch/ path, copy the scripts into ci/scripts/, and remove the temporary checkout. The packaging branch has no ci/ directory so there is no conflict. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
…h invocation Two fixes: 1. pkg-linux-qcom-ref was not passed from daily.yml/release.yml to build-kernel-deb.yml, so the prepare job always checked out qcom/debian/latest regardless of which packaging branch was intended. This caused prepare-source.sh to be the old version (without --srcpkg, --binpkg, --kernel-config flags), which errored on the new flags passed by the workflow, leaving debian/changelog ungenerated. The Debusine build job then failed with 'cannot open file debian/changelog'. Fix: add pkg_linux_qcom_ref as a matrix field and thread it through daily.yml and release.yml into build-kernel-deb.yml as pkg-linux-qcom-ref. Defaults to qcom/debian/latest when not set in the matrix row. 2. ci/build-matrix.json: set pkg_linux_qcom_ref to feat/matrix-expansion-packaging for validation builds so the prepare job uses the new prepare-source.sh. Will be updated to qcom/debian/latest once feat/matrix-expansion-packaging is merged. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
docker-pkg-build and pkg-builder only support trixie for Debian-family suites. Forky and sid builds were failing at the 'Build docker image' step because docker_deb_build.py does not accept forky as a distro. The docker container is used only for source preparation (prepare-source.sh runs inside pkg-builder:trixie). The actual suite-specific kernel build happens inside Debusine, which handles forky and sid natively. Pinning the docker image to trixie for all Debian-family suites is therefore correct and sufficient. Changes: - build-kernel-deb.yml: add DOCKER_DISTRO env var to the prepare job. Resolves to trixie for forky/sid/unstable, passes through the real suite for Ubuntu-family (noble, questing, resolute). Both docker_deb_build.py and pkg-builder container now use DOCKER_DISTRO. - build-kernel-debusine.yml: pin debusine-pkg-builder container to trixie in both the build and release jobs. The container is used only for dpkg-buildpackage -S (source package generation) and lib/release (Debusine promotion), neither of which is suite-specific. - ci/build-matrix.json: add resolute to the Daily suites array. Resolute is classified as ubuntu-family by the resolve job and routed through build-kernel-ubuntu.yml unchanged. When Debusine gains resolute support, only the resolve job classification needs updating -- no matrix change. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Three silent correctness bugs introduced when the matrix expanded from
one suite per family to N:
1. Artifact name collision (kernel-srcpkg shared across all legs)
actions/download-artifact resolves a duplicated name to the newest
artifact, so every consumer received whichever prepare job finished
last rather than its own tree. Confirmed in run 30053624870: all
three consumer jobs downloaded artifact 8582070626 (trixie's tree)
regardless of suite. Suffix the name with the suite at all three
sites: upload in build-kernel-deb.yml and downloads in
build-kernel-debusine.yml and build-kernel-ubuntu.yml.
2. JOB_INDEX hardcoded to "0" (Debusine child workspace collision)
Both Debian-family legs of a run computed the identical child
workspace name qli-ci-gh-<run_id>-1-0, so only the first
create_child_workspace succeeded. This was the real cause of every
forky Debusine failure, not a missing suite configuration on the
server. Confirmed in run 30053624870: trixie (WR 30423, success at
23:43:56) and forky (WR 30425, failure at 23:44:04) printed the
same workspace string. Pass JOB_INDEX: ${{ inputs.suite }} so each
leg gets a distinct suffix.
3. pkg_linux_qcom_ref pinned to the unmerged feature branch
Both matrix rows carried "pkg_linux_qcom_ref":
"feat/matrix-expansion-packaging", making the
|| 'qcom/debian/latest' fallbacks in daily.yml and release.yml
unreachable dead code. After merge, every build would check out the
feature branch; after branch deletion, every build would fail at
actions/checkout. Delete the key from both rows so the fallback
takes effect.
Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
…tions Four independent issues addressed: 1. kernel-config default bypassed on empty explicit input build-kernel-deb.yml:325 used || '' where the sibling lines use || 'default-value'. A workflow_call default: never applies to an explicitly empty input, so a matrix row omitting kernel_config passed an empty string, the [[ -n ]] guard skipped --kernel-config, and the kernel shipped with zero config fragments while exiting 0. Change || '' to || 'squashfs,...' matching the workflow_dispatch default and the current matrix rows. 2. target_workspace: "qli" on the Daily row is a landmine The Daily row carried target_workspace: "qli" as dead data. daily.yml intentionally omits target-workspace from its with: block, so the field has no effect today. But it is one line away from turning every scheduled nightly into a production promotion into qli using DEBUSINE_RELEASE_TOKEN, because build-kernel-debusine.yml gates purely on the field being empty or not. Remove it from the Daily row; it belongs only on Release rows. 3. target-workspace on workflow_dispatch with no approval gate Any write-access user could set target-workspace on a direct build-kernel-deb.yml dispatch and promote arbitrary builds to production without going through release.yml. Update the description to make clear this input is only for release.yml; a follow-up can add environment: production once the release path is validated. 4. Single-suite manual dispatch hard-failed for most dropdown options resolve-matrix.sh raises jq error() when --single-suite names a suite absent from the matrix. daily.yml offered 6 suites against a Daily row carrying 2 (trixie, resolute); 4 of 6 options aborted configure-matrix. release.yml offered 4 options against a Release row carrying 1 (trixie); 3 of 4 aborted. The empty-string default in release.yml also triggered an actionlint warning. Trim both dropdowns to the suites their matrix rows actually carry. Replace release.yml's empty-string option with an 'all' sentinel and wire the configure-matrix step to treat both empty and 'all' as the full-matrix path. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
The Debusine workspace collision bug (JOB_INDEX hardcoded to "0") caused both Debian-family legs to compute the identical child workspace name, making forky's create_child_workspace fail seconds after trixie's succeeded. That root cause was fixed in d751b30 by keying JOB_INDEX on the suite name, giving each leg a distinct workspace suffix. Forky can now run in parallel with trixie without collision. Add forky to both the Daily and Release suites arrays, and add it to the workflow_dispatch dropdown options in daily.yml and release.yml so single-suite manual dispatches work correctly. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Extend ci/build-matrix.json from a qcom-next-specific configuration into a kernel-variant delivery contract. Each variant must define exactly one Daily row and one Release row, keep one srcpkg and binpkg across that pair, and use package identities that are not shared by another variant. Validate required matrix fields, suite lists, delivery type, ref strategy, tag-pattern usage, and Release target-workspace requirements before generating any workflow legs. Flatten each row's suites into independent variant-and-suite entries and allow resolution by delivery type, variant, and suite. Thread the resulting metadata through Daily, Release, and build-kernel-deb: kernel repository, branch or tag, ref strategy, package identities, config fragments, Debian revision, LOCALVERSION/KVER_EXTRA overrides, packaging ref, and Debusine workspace data. Make the execution paths variant-safe. Prepared-source artifacts use the variant and suite, Debusine JOB_INDEX uses the same pair, and Debian and Ubuntu S3 destinations include the variant and suite. Generalize ref resolution and LOCALVERSION derivation so dated tags produce -<variant>-<date>, while branch tips use a short commit SHA. Retain Debian-versus-Ubuntu suite routing while propagating the variant identity through both reusable build paths. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Replace the ambiguous manual-dispatch controls with explicit matrix scopes. Daily supports Full matrix, Selected variant (all suites), and Selected variant and suite; scheduled Daily runs always select the full matrix. Each scope maps directly to resolve-matrix.sh arguments, so a manual run expands exactly the intended set of flattened matrix legs without empty values or an `all` sentinel. Constrain Release promotion to one kernel variant. The default Release scope promotes all configured Release suites for the selected variant; the targeted scope promotes one selected suite. Remove full-matrix Release promotion so a new matrix variant cannot be promoted accidentally by an unrelated release. Release continues to take its pinned ref, package metadata, Debian revision, packaging ref, and target workspace exclusively from the selected matrix row. Restructure build-kernel-deb dispatch inputs around kernel variant, suite, and ref strategy. Use latest_tag, branch_tip, and pinned_ref as explicit strategies and mark package, configuration, version, repository, and PR inputs as advanced overrides. Keep direct dispatch build-only; Release promotion remains owned by release.yml. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Rewrite the README around the matrix-driven delivery model. Define the per-variant Daily/Release pair, flattened suite legs, required row fields, ref-strategy constraints, package-identity rules, and the onboarding procedure for an additional kernel variant. Document the end-to-end data flow with diagrams for prepared-source artifacts, Debian source package generation and Debusine binary builds, Daily S3 publication, Release package-publish promotion, and the Ubuntu Docker path. Describe variant-and-suite isolation at the GitHub artifact, Debusine workspace, and S3 boundaries. Document generated source, versioned image, metapackage, headers, and debug packages; Debian rc version ordering; direct-build inputs; repository variables and secrets; and the production baseline: Production GitHub environment, qli Release workspace, 0qli~/0qli revisions, and qcom/debian/latest packaging ref. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
force-pushed
the
feat/matrix-expansion-ci
branch
2 times, most recently
from
August 19, 2026 19:37
4acf777 to
7c1ccef
Compare
Bjordis Collaku (bjordiscollaku)
added a commit
that referenced
this pull request
Aug 19, 2026
The Copyright and License Check on PR #63 flagged derive-debian-revision.sh, derive-localversion.sh, resolve-kernel-ref.sh, and resolve-matrix.sh as missing a license header. Add the standard two-line header (Qualcomm copyright notice plus SPDX-License-Identifier: BSD-3-Clause-Clear, matching LICENSE.txt) to each. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
added a commit
that referenced
this pull request
Aug 19, 2026
The security scan (zizmor) and Semgrep OSS checks on PR #63 both flagged genuine issues: - build-kernel-deb.yml, daily.yml, and release.yml interpolated workflow_dispatch/workflow_call inputs and github.event.inputs.* directly into run: shell blocks via ${{ }}. That expansion happens as literal text substitution before the shell parses anything, so a value containing shell metacharacters could inject commands into the runner. Move every such input into a step-level env: mapping and reference it as a quoted shell variable instead, which passes the value at process-invocation time rather than templating it into the script text. daily.yml was not flagged by either scanner but carried the identical pattern as release.yml, so it gets the same fix for consistency. - daily.yml and release.yml called build-kernel-deb.yml with secrets: inherit, granting it every secret available to the caller even though it only ever forwards three Debusine secrets to build-kernel-debusine.yml. Declare those three secrets explicitly on build-kernel-deb.yml's workflow_call trigger and pass only them by name from daily.yml and release.yml, per least privilege. No behavioral change: every relocated value resolves to the same string at run time, and the explicit secrets map forwards exactly the secrets already in use. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 19, 2026 20:29 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 19, 2026 20:29 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 19, 2026 20:30 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 19, 2026 20:31 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 19, 2026 21:16 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 19, 2026 21:17 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
added a commit
that referenced
this pull request
Aug 19, 2026
The Copyright and License Check on PR #63 flagged derive-debian-revision.sh, derive-localversion.sh, resolve-kernel-ref.sh, and resolve-matrix.sh as missing a license header. Add the standard two-line header (Qualcomm copyright notice plus SPDX-License-Identifier: BSD-3-Clause-Clear, matching LICENSE.txt) to each. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
added a commit
that referenced
this pull request
Aug 19, 2026
The security scan (zizmor) and Semgrep OSS checks on PR #63 flagged genuine issues across every reusable and top-level workflow: - build-kernel-deb.yml, build-kernel.yml, build-kernel-debusine.yml, daily.yml, and release.yml interpolated workflow_dispatch/workflow_call inputs, github.event.inputs.*, secrets.*, and steps.*.outputs.* directly into run: shell blocks via ${{ }}. That expansion happens as literal text substitution before the shell parses anything, so a value containing shell metacharacters could inject commands into the runner - including, for the docker run --privileged invocations in build-kernel.yml, directly on the self-hosted host rather than merely inside the container. Move every such value into a step-level env: mapping (forwarded into containers via docker run -e) and reference it as a quoted shell variable instead, which passes the value at process-invocation time rather than templating it into the script text. daily.yml was not flagged by either scanner but carried the identical pattern as release.yml, so it gets the same fix for consistency. - daily.yml and release.yml called build-kernel-deb.yml with secrets: inherit, granting it every secret available to the caller even though it only ever forwards three Debusine secrets to build-kernel-debusine.yml. Declare those three secrets explicitly on build-kernel-deb.yml's workflow_call trigger and pass only them by name from daily.yml and release.yml, per least privilege. No behavioral change: every relocated value resolves to the same string at run time, and the explicit secrets map forwards exactly the secrets already in use. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
force-pushed
the
feat/matrix-expansion-ci
branch
from
August 19, 2026 21:28
577d39d to
7b19d93
Compare
Debusine accepted the identical binary package version into both trixie and forky, making repository object identity ambiguous and later causing pool-object downloads to fail. Storing one complete debian_revision per matrix row cannot prevent this: nothing stops two suites from resolving to the same string. Restructure ci/build-matrix.json so each row carries a debian_version_stub and a matrix-wide suite_suffix_mapping supplies the per-suite Debian suffix. Each row also carries a debian_version_suffix: "~" for Daily, empty for Release. This is the delivery-type half of the same formula, computed via an explicit case statement rather than a ternary so the Daily/Release branching stays self-documenting; storing it on the row makes it visible next to debian_version_stub instead of only inside the derivation script. debian_revision = debian_version_stub + suite_suffix_mapping[suite] + debian_version_suffix ci/scripts/derive-debian-revision.sh is the single implementation of this formula, used both by resolve-matrix.sh for matrix-driven Daily/Release legs and by build-kernel-deb.yml's direct dispatch path, which has no full-matrix context. resolve-matrix.sh rejects a debian_version_stub that ends in ~, a matrix where any configured suite has no suite_suffix_mapping entry, where two suites share a suffix, where a suffix is malformed, where a variant's Daily and Release rows disagree on debian_version_stub, or where a row's debian_version_suffix disagrees with its own type, before any build job starts. Derivation still computes the suffix from type internally; the row field is consumed and stripped before a leg is emitted, so it never reaches build-kernel-deb.yml. derive-debian-revision.sh independently re-validates suite_suffix_mapping before deriving anything, since build-kernel-deb.yml's direct-dispatch path calls it standalone, without resolve-matrix.sh's validation pass having run first. build-kernel-deb.yml's advanced manual-dispatch input is renamed from debian-revision to debian-version-stub; direct dispatch always resolves using Daily semantics since it is build-only and non-promoting. The workflow_call interface used by daily.yml and release.yml is unchanged, since resolve-matrix.sh already supplies the fully-derived revision. Update README.md to match: replace the debian_revision matrix examples with debian_version_stub, debian_version_suffix, and the shared suite_suffix_mapping, add derived Daily/Release examples per suite, explain the resulting ordering model including the case where Daily revisions across two suites do not sort relative to each other, note the new Daily/Release consistency check resolve-matrix.sh performs on debian_version_suffix, and add suite-onboarding steps alongside the existing variant-onboarding steps. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
The Copyright and License Check on PR #63 flagged derive-localversion.sh, resolve-kernel-ref.sh, and resolve-matrix.sh as missing a license header. Add the standard two-line header (Qualcomm copyright notice plus SPDX-License-Identifier: BSD-3-Clause-Clear, matching LICENSE.txt) to each. derive-debian-revision.sh already carries the header from the commit that introduced it. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
added a commit
that referenced
this pull request
Aug 19, 2026
The security scan (zizmor) and Semgrep OSS checks on PR #63 flagged genuine issues across every reusable and top-level workflow: - build-kernel-deb.yml, build-kernel.yml, build-kernel-debusine.yml, daily.yml, and release.yml interpolated workflow_dispatch/workflow_call inputs, github.event.inputs.*, secrets.*, and steps.*.outputs.* directly into run: shell blocks via ${{ }}. That expansion happens as literal text substitution before the shell parses anything, so a value containing shell metacharacters could inject commands into the runner - including, for the docker run --privileged invocations in build-kernel.yml, directly on the self-hosted host rather than merely inside the container. Move every such value into a step-level env: mapping (forwarded into containers via docker run -e) and reference it as a quoted shell variable instead, which passes the value at process-invocation time rather than templating it into the script text. daily.yml was not flagged by either scanner but carried the identical pattern as release.yml, so it gets the same fix for consistency. - daily.yml and release.yml called build-kernel-deb.yml with secrets: inherit, granting it every secret available to the caller even though it only ever forwards three Debusine secrets to build-kernel-debusine.yml. Declare those three secrets explicitly on build-kernel-deb.yml's workflow_call trigger and pass only them by name from daily.yml and release.yml, per least privilege. No behavioral change: every relocated value resolves to the same string at run time, and the explicit secrets map forwards exactly the secrets already in use. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
force-pushed
the
feat/matrix-expansion-ci
branch
2 times, most recently
from
August 21, 2026 18:04
1f881fa to
1f57893
Compare
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 21, 2026 18:17 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 21, 2026 18:18 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 21, 2026 18:18 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 21, 2026 18:19 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 21, 2026 18:59 — with
GitHub Actions
Inactive
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 21, 2026 19:18 — with
GitHub Actions
Inactive
The security scan (zizmor) and Semgrep OSS checks on PR #63 flagged genuine issues across every reusable and top-level workflow: - build-kernel-deb.yml, build-kernel.yml, build-kernel-debusine.yml, daily.yml, and release.yml interpolated workflow_dispatch/workflow_call inputs, github.event.inputs.*, secrets.*, and steps.*.outputs.* directly into run: shell blocks via ${{ }}. That expansion happens as literal text substitution before the shell parses anything, so a value containing shell metacharacters could inject commands into the runner - including, for the docker run --privileged invocations in build-kernel.yml, directly on the self-hosted host rather than merely inside the container. Move every such value into a step-level env: mapping (forwarded into containers via docker run -e) and reference it as a quoted shell variable instead, which passes the value at process-invocation time rather than templating it into the script text. daily.yml was not flagged by either scanner but carried the identical pattern as release.yml, so it gets the same fix for consistency. - daily.yml and release.yml called build-kernel-deb.yml with secrets: inherit, granting it every secret available to the caller even though it only ever forwards three Debusine secrets to build-kernel-debusine.yml. Declare those three secrets explicitly on build-kernel-deb.yml's workflow_call trigger and pass only them by name from daily.yml and release.yml, per least privilege. No behavioral change: every relocated value resolves to the same string at run time, and the explicit secrets map forwards exactly the secrets already in use. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Use qcom-next-7.2-rc7-20260821 for the staging Release validation. The upstream version changes with this tag, giving the generated orig tarball a new pool filename while retaining the existing staging Debian revision. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Overlay staging validation settings on the production-ready delivery model. Run Debusine build and promotion jobs in the Staging GitHub environment, direct Release promotion to qli-staging, and use 0qli+staging1 as the Debian version stub for both Daily and Release builds (the Daily/Release delivery suffix is derived automatically). Point matrix preparation at feat/matrix-expansion-packaging and align the direct-build stub default and README input table with the staging stub. Keep this as the branch-tip commit. Reverting it restores Production, qli, 0qli, and qcom/debian/latest without changing matrix behavior, dispatch semantics, package generation, or workflow topology. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Bjordis Collaku (bjordiscollaku)
force-pushed
the
feat/matrix-expansion-ci
branch
from
August 21, 2026 22:53
1f57893 to
8d44210
Compare
Bjordis Collaku (bjordiscollaku)
deployed
to
Staging
August 21, 2026 23:01 — with
GitHub Actions
Active
Bjordis Collaku (bjordiscollaku)
temporarily deployed
to
Staging
August 21, 2026 23:02 — with
GitHub Actions
Inactive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
The CI model is matrix-driven. This repository can deliver multiple kernel variants, each with independent source and package identity, kernel source and ref strategy, configuration fragments, Debian revision, target suites, packaging ref, and Release destination.
Every kernel variant owns exactly two complete matrix rows: one
Dailyrow and oneReleaserow. The matrix resolver expands every suite in those rows into an isolatedkernel_variant + suitebuild leg.Adding a new kernel variant is a two-row matrix change, not a workflow redesign.
Matrix Model
The current staging-validation rows illustrate the full delivery contract:
qcom-nextqcom-nexttrixie,forky,resolutetrixie,forkyqualcomm-linux/kernelqualcomm-linux/kernelqcom-next-*tagqcom-nexttag familyqcom-next-7.2-rc7-20260821linux-qcom-nextlinux-qcom-nextlinux-image-qcom-nextlinux-image-qcom-nextdebian_version_stub+ suite suffix +~debian_version_stub+ suite suffixfeat/matrix-expansion-packagingfeat/matrix-expansion-packagingqli-stagingDebian revision is derived, not stored per row. Every variant's Daily and Release rows share one
debian_version_stub; a matrix-widesuite_suffix_mappingsupplies the suite-specific part so two suites in the same delivery never receive an identical Debian revision. For the current staging stub (0qli+staging1) and mapping (trixie: ~bpo13+1,forky: empty,resolute: ~26.04.1):0qli+staging1~bpo13+1~0qli+staging1~bpo13+10qli+staging1~0qli+staging10qli+staging1~26.04.1~This directly fixes a real defect found during target APT validation: Debusine accepted the identical binary package version into both
trixieandforky, making the two suites' pool objects ambiguous and returning an HTTP 500 on pool-object download.ci/scripts/derive-debian-revision.shis the single implementation of the formula; bothresolve-matrix.shandbuild-kernel-deb.yml's direct-dispatch path call it, so revision derivation cannot drift between the matrix-driven and manual paths.Each flattened suite leg carries its own values and uses a distinct prepared-source artifact, Debusine child workspace, and publication identity. Parallel suites and future variants therefore cannot share inputs or outputs.
Daily and Release
Daily
Daily is the recurring build and artifact-publication path.
latest_tagresolves the newest matching dated tag.branch_tipresolves the configured branch directly..deboutputs are downloaded from the isolated CI workspace and published to S3.Release
Release is the controlled package-promotion path.
package-publishto the selected target workspace.build-kernel-deb.ymldispatches are build-only. Release promotion is initiated exclusively byrelease.yml.Architecture
flowchart LR IN["Matrix variant + suite input"] --> R{"Resolve suite family"} R -->|"trixie · forky"| DEB["Debian path\nbuild-kernel-debusine.yml\nGenerate source package\nSubmit with lib/build\nDebusine builds binaries"] R -->|"resolute"| UBU["Ubuntu path\nbuild-kernel-ubuntu.yml\nbuild-kernel.sh in Docker\nBuild binary packages"] DEB --> DOUT{"Build type"} DOUT -->|Daily| S3["Download .deb files\nPublish to S3"] DOUT -->|Release| QLI["Promote source and binaries\nto qli"] UBU --> US3["Publish .deb files to S3"]Pipeline Overview
flowchart TD subgraph triggers[Triggers] A1["daily.yml\nScheduled full matrix"] A2["daily.yml\nManual full matrix or selected variant and suite"] A3["release.yml\nManual selected variant, with optional suite"] A4["build-kernel-deb.yml\nManual build-only validation"] end subgraph matrix[Matrix entry points] B1["Daily configure-matrix\nFlatten Daily rows"] B2["Daily variant + suite legs\nqcom-next / trixie · forky · resolute"] B3["Release configure-matrix\nFlatten Release rows"] B4["Release variant + suite legs\nqcom-next / trixie · forky"] end subgraph orchestrator[Reusable build workflow] C1["Resolve suite family"] C2["Prepare selected kernel and packaging source\nUpload an isolated prepared-source artifact"] C3["Debian build path"] C4["Ubuntu build path"] end subgraph outputs[Outputs] D1["Daily S3 artifacts"] D2["Release Debusine APT repository"] end A1 --> B1 A2 --> B1 A3 --> B3 B1 --> B2 --> C1 B3 --> B4 --> C1 A4 --> C1 C1 --> C2 C2 --> C3 & C4 C3 --> D1 & D2 C4 --> D1Implementation
LOCALVERSIONderivation.debian_version_stuband matrix-widesuite_suffix_mappingvia a newci/scripts/derive-debian-revision.sh, so Daily and Release rows store one stub instead of a duplicated, suite-blinddebian_revision.forkyto Daily and Release coverage andresoluteto Daily coverage.build-kernel.ymlandbuild-kernel-debusine.ymlflagged by the repository's required workflow-security scan, moving every${{ }}reference out ofrun:script bodies into step-levelenv:.Validation
qcom-next-7.2-rc7-20260821built and promoted successfully for bothtrixieandforkyin the same run, each receiving its own distinct Debian revision (0qli+staging1~bpo13+1fortrixie,0qli+staging1forforky).qli-stagingcarries the full versioned image, image metapackage, versioned and metapackage headers, and debug packages for bothtrixieandforky, each under its own suite-specific version string.Target validation
Pulling the
trixiepackage directly onto a live target, before upgrade the three prior kernels (including the previous20260817collision-fix validation build) are installed:No
Err:lines and no HTTP 500 anywhere in the transfer or install, the exact failure mode this PR fixes. Post-reboot, the target booted the new kernel cleanly and it coexists with all three prior kernels:All four kernels remain installed side by side with no dpkg conflict, and systemd-boot carries a loader entry for each, confirming the version-collision fix holds: distinct suite-specific revisions produce distinct pool objects, so nothing here collides.
Version-collision fix
suite_suffix_mapping(introduced in this PR) is what makes the target validation above possible: each suite gets its own Debian revision instead of the single shareddebian_revisionthis branch started with, which is what lettrixieandforkycollide on an identical version in the first place. Daily S3 artifacts for this ref, distinctly versioned per suite:The Release run's
Release to Debusinestep reportedresult=successfor both suites, publishing distinct binary-package entries intoqli-staging:Dependencies
qli-staging, staging revisions, andfeat/matrix-expansion-packaging.Before Merge
Productionqlidebian_version_stub(shared by Daily and Release):0qliqcom/debian/latestsuite_suffix_mappingis suite-identity policy, not a staging artifact; it carries over to production unchanged.