Skip to content

feat(ci): release & distribution pipeline — ADR 0003 + scaffold workflow#405

Open
Matovidlo wants to merge 5 commits into
mainfrom
martinvasko-release-distribution-cicd
Open

feat(ci): release & distribution pipeline — ADR 0003 + scaffold workflow#405
Matovidlo wants to merge 5 commits into
mainfrom
martinvasko-release-distribution-cicd

Conversation

@Matovidlo

@Matovidlo Matovidlo commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Ships kbagent as a self-contained native binary (no Python / no uv on the user's machine) packaged for brew / apt / dnf / apk / chocolatey / winget — the same install UX the legacy Go kbc delivered — under the keboola-cli2 package name so it coexists with the legacy kbc.

  • ADR 0003 (docs/adr/0003-release-distribution-cicd.md): the decision record — PyPI via OIDC Trusted Publishing, a PyInstaller freeze matrix (linux amd64/arm64, macOS arm64, windows amd64), sign/notarize, nfpm for deb/rpm/apk, Homebrew/Chocolatey/WinGet wrappers, publishing to cli-dist.keboola.com. Includes the required release secrets (where to get + how to set).
  • Release pipeline (.github/workflows/release-kbagent.yml): tag-triggered (v*.*.*), real (not stubbed). Jobs: versiongatepypi / freeze (matrix) → package-linuxgithub-release / publish-s3homebrew / chocolatey / wingettest-install.
  • Packaging sources under build/package/** (entry point, nfpm config, per-OS sign/notarize, repo indexing, Homebrew/Chocolatey templates) + a setup-build composite action.

Safety / gating

  • Real publishing happens ONLY on a pushed v*.*.* tag. Every external-publish job (pypi, publish-s3, homebrew, chocolatey, winget, github-release) is gated on startsWith(github.ref, 'refs/tags/').
  • workflow_dispatch is a DRY RUN: it freezes + signs + packages (exercising the build and signing creds) but publishes nothing externally.
  • Pre-release tags (PEP 440 b/rc/.dev) build + package + GitHub pre-release only; all external publishing is skipped.
  • Publish jobs run under the protected release environment; the gate job re-runs the per-PR checks against the tagged commit and fails fast if the tag version ≠ pyproject.toml.
  • GoReleaser is NOT used (it builds Go); nothing depends on the deprecated keboola-as-code repo.

Coexistence with the legacy kbc

Distinct package name (keboola-cli2), distinct S3 prefix (keboola-cli2/), distinct Homebrew tap (keboola/homebrew-keboola-cli2), distinct Chocolatey/WinGet ids — verified no collision with the existing kbc distribution.

Change type

CI + docs + packaging sources. No application/CLI source changes (the only Python added is a 3-line PyInstaller entry point). No version bump.

Test plan

  • Validated end-to-end through dev tags: 4-OS freeze, macOS + Windows signing, nfpm deb/rpm/apk, GitHub (pre-)release with all assets, frozen binary runs with no Python (env -i kbagent --version).
  • release-kbagent.yml + setup-build/action.yml parse as valid YAML; index.sh passes bash -n.
  • Smoke test (test-install) installs via apt + Homebrew and asserts kbagent --version.
  • Remaining items only exercised on a real prod tag: AWS role permission for cli-dist-keboola-com/keboola-cli2/*, HOMEBREW_TAP_TOKEN push, first-time WinGet submission.

Deployment

Merge is inert until a v*.*.* tag is pushed and the release environment + secrets are configured.

Rollback plan

Revert of this PR; delete any published tag/release.

self-review skipped: /kbagent:review requires the kbagent Claude Code plugin; ran a thermo-nuclear + ponytail structural pass instead.

@Matovidlo

Copy link
Copy Markdown
Contributor Author

@claude review

@Matovidlo Matovidlo requested a review from Copilot June 10, 2026 09:51
@Matovidlo Matovidlo force-pushed the martinvasko-release-distribution-cicd branch from 3c9c953 to fc19fa4 Compare June 10, 2026 09:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a proposed ADR and a new tag-triggered GitHub Actions workflow scaffold to define and begin implementing kbagent’s future release/distribution CI/CD (wheel build → PyPI via OIDC, later Nuitka freeze + packaging), while keeping publishing steps stubbed for safety.

Changes:

  • Add ADR 0003 describing the target release/distribution pipeline, rollout phases, and required release secrets.
  • Add a scaffold release-kbagent workflow with gated checks/tests, wheel build + artifact upload, and stubbed publish/freeze/package stages.
  • Introduce a release pipeline structure intended to align with existing CI jobs (but currently not fully mirrored).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
docs/adr/0003-release-distribution-cicd.md New ADR documenting the planned release & distribution CI/CD approach and rollout.
.github/workflows/release-kbagent.yml New tag-based release workflow scaffold (gating, wheel build, stubbed publish/freeze/package jobs).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/adr/0003-release-distribution-cicd.md Outdated
Comment thread docs/adr/0003-release-distribution-cicd.md
Comment thread docs/adr/0003-release-distribution-cicd.md Outdated
Comment thread .github/workflows/release-kbagent.yml
Comment thread .github/workflows/release-kbagent.yml
Comment thread .github/workflows/release-kbagent.yml Outdated
@Matovidlo Matovidlo force-pushed the martinvasko-release-distribution-cicd branch 2 times, most recently from 429d7f0 to f0c5cd4 Compare June 10, 2026 10:10
@soustruh

Copy link
Copy Markdown

Oh, it's funny I was going to address a similar thing, can you please hold this PR until I send another commit or a comment for your agent to this PR pls? 🙏

@Matovidlo

Copy link
Copy Markdown
Contributor Author

@soustruh yes feel free

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.

Comment thread build/package/linux/index.sh
Comment thread build/package/linux/index.sh Outdated
Comment thread build/package/windows/sign.sh Outdated
Comment thread build/package/macos/sign_notarize.sh Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.

Comment thread build/package/linux/index.sh Outdated
Comment thread build/package/linux/index.sh
Comment thread build/package/windows/sign.sh
Comment thread .github/workflows/release-kbagent.yml

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/release-kbagent.yml
Comment thread .github/workflows/release-kbagent.yml
Comment thread build/package/windows/sign.sh

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 6 comments.

Comment thread .github/workflows/release-kbagent.yml
Comment thread .github/workflows/release-kbagent.yml
Comment thread build/package/linux/index.sh
Comment thread build/package/linux/index.sh
Comment thread .github/workflows/release-kbagent.yml Outdated
Comment thread build/package/macos/sign_notarize.sh Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 7 comments.

Comment thread .github/actions/setup-build/action.yml
Comment thread .github/workflows/release-kbagent.yml Outdated
Comment thread .github/workflows/release-kbagent.yml Outdated
Comment thread .github/workflows/release-kbagent.yml Outdated
Comment thread .github/workflows/release-kbagent.yml Outdated
Comment thread .github/workflows/release-kbagent.yml Outdated
Comment thread .github/workflows/release-kbagent.yml

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 2 comments.

Comment thread docs/adr/0003-release-distribution-cicd.md Outdated
Comment thread build/package/windows/sign.sh
@Matovidlo Matovidlo force-pushed the martinvasko-release-distribution-cicd branch 2 times, most recently from 7e73ab3 to a3d25f8 Compare June 18, 2026 09:18
@Matovidlo Matovidlo requested a review from padak June 18, 2026 10:08
Decision record for shipping kbagent as a self-contained native binary
(PyInstaller) packaged for brew/apt/dnf/apk/chocolatey/winget under the
keboola-cli2 name, coexisting with the legacy Go kbc. Covers PyPI OIDC
publishing, the nfpm packaging choice (not goreleaser), signing/notarization,
and the required release secrets.
…+ nfpm)

Tag-triggered (v*.*.*) pipeline that freezes kbagent into a self-contained
native binary and publishes it across all major package managers, giving the
same install UX as the legacy Go kbc without requiring Python/uv on the user's
machine. workflow_dispatch is a dry run (freeze + sign + package only);
external publishing is gated on refs/tags/* and the protected release env.

- .github/workflows/release-kbagent.yml: version → gate → pypi/freeze(matrix)
  → package-linux → github-release/publish-s3 → homebrew/chocolatey/winget →
  test-install. Pre-release (PEP 440 b/rc/.dev) tags build + GitHub pre-release
  only; gate fails fast if the tag version != pyproject.toml.
- .github/actions/setup-build: composite pinning uv + Python 3.12 (+ optional Node).
- build/package: PyInstaller entry point, nfpm config (deb/rpm/apk), per-OS
  sign/notarize (macOS notarytool, Windows Azure Key Vault + jsign), signed
  apt/rpm/apk repo indexing, Homebrew formula + Chocolatey wrappers.
- .gitignore: track build/package/ (packaging sources) while still ignoring build artifacts.
@Matovidlo Matovidlo force-pushed the martinvasko-release-distribution-cicd branch from a3d25f8 to 2b7a6af Compare June 18, 2026 10:20

@padak padak left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of #405 — feat(ci): release & distribution pipeline — ADR 0003 + scaffold workflow

Generated by kbagent-pr-reviewer subagent. Verdict and findings below
are advisory; the human author retains every veto. CI-coverable issues
(lint, format, tests) are confirmed via make check, not duplicated here.

Summary

This PR ships a complete tag-triggered release pipeline (release-kbagent.yml) that freezes a self-contained kbagent binary via PyInstaller for linux amd64/arm64, macOS arm64, and Windows amd64, then packages and publishes via nfpm (deb/rpm/apk), Homebrew, Chocolatey, WinGet, and PyPI. It also adds an ADR (0003), the composite setup-build action, packaging config under build/package/, and a .gitignore update. The PR description correctly classifies this as CI + docs + packaging only — no application source changes, no new CLI commands — so the Plugin synchronization map is not applicable. make check passes cleanly (4124 passed, 8 skipped). The overall design is solid: real jobs, correct gating, supply-chain-conscious (nfpm hash-verified, jsign hash-verified, wingetcreate Authenticode-checked before execution). Three non-blocking issues and four nits need attention. Verdict: COMMENT (no blocking findings).

Verdict

  • Verdict: COMMENT
  • Blocking findings: 0
  • Non-blocking findings: 3
  • Nits: 4

Blocking findings

(none)

Non-blocking findings

[NB-1] .github/workflows/release-kbagent.yml:74-76 — workflow-level id-token: write + contents: write granted to every job

Top-level permissions: propagates id-token: write (OIDC token capable of assuming AWS/PyPI roles) and contents: write (can create/delete GitHub Releases and push tags) to jobs that need neither — specifically version, gate, freeze (signing only), and package-linux. The existing release.yml in this repo scopes contents: write at the workflow level too, so this matches the current pattern, but the release workflow is a higher-value target: it runs on tag pushes and mints OIDC tokens worth real-world credentials.

Fix: scope permissions per-job — give contents: write only to github-release, id-token: write only to pypi and publish-s3. Every other job can run with the default contents: read / no OIDC token. This is the GitHub recommended pattern for release workflows.

[NB-2] docs/adr/0003-release-distribution-cicd.md:908 — ADR claims "macOS amd64/arm64" but the workflow only builds arm64

The ADR's decision prose ("Freezes native kbagent binaries... across a matrix (linux amd64/arm64, macOS amd64/arm64, windows amd64)") says two macOS arches, but the freeze matrix in .github/workflows/release-kbagent.yml:163-168 has a single { os: macos-latest, platform: darwin, arch: arm64 } entry with an explicit comment that Intel Macs are excluded. The Homebrew formula correctly handles this with an on_intel do / odie block. The inconsistency is in the ADR text only — the workflow is intentionally correct — but the ADR will mislead future contributors who read it.

Fix: change the ADR line 908 to "macOS arm64 (Apple Silicon only; Intel Macs fall back to uv tool install)" and reference the macos-13 comment in the workflow for re-enabling the Intel leg.

[NB-3] docs/adr/0003-release-distribution-cicd.md:958 — ADR secrets table lists DEB_KEY_PUBLIC but it is not used

The secrets table in the ADR (line 958) lists DEB_KEY_PRIVATE / DEB_KEY_PUBLIC as a required secret pair. However build/package/linux/index.sh:621 explicitly documents that the apt keyring (keboola.gpg) is derived from DEB_KEY_PRIVATE (via gpg --export) and there is no DEB_KEY_PUBLIC variable referenced anywhere in the scripts or workflow jobs. The publish-s3 job (release-kbagent.yml:313) only passes DEB_KEY_PRIVATE. Whoever sets up the release environment secrets will add DEB_KEY_PUBLIC unnecessarily, or worse, wonder why the workflow never consumes it and assume the table is stale.

Fix: Remove DEB_KEY_PUBLIC from the ADR secrets table and add a parenthetical "(public half exported inline from DEB_KEY_PRIVATE by index.sh)".

Nits

  • [NIT-1] docs/adr/0003-release-distribution-cicd.md:5 — ADR status is Proposed but it will be Accepted (merged). Convention in this repo: ADR 0001 and 0002 both say Accepted. Update to Accepted before merge.

  • [NIT-2] .github/workflows/release-kbagent.yml:336cpina/github-action-push-to-another-repository@v1.7.2 is pinned to a version tag, not a commit SHA. The official GitHub hardening guide recommends SHA pins for third-party actions to avoid tag mutable-repoint attacks. The softprops/action-gh-release@v2, pypa/gh-action-pypi-publish@release/v1, and aws-actions/configure-aws-credentials@v6 have the same pattern. The actions/* actions (GitHub-owned) are conventionally considered safe at @v5/@v6, but the third-party ones (cpina, softprops, pypa, aws-actions) are higher-risk. At minimum, pin cpina/github-action-push-to-another-repository to a SHA given that it receives API_TOKEN_GITHUB with write access to the tap repo.

  • [NIT-3] .github/workflows/release-kbagent.yml:202-203APPLE_ACCOUNT_USERNAME: apple@keboola.com and APPLE_TEAM_ID: 46P6KJ65M2 are hardcoded as literals in the workflow's env: block rather than referencing secrets or workflow-level env vars. Apple Team IDs and Apple ID emails are not secret, but embedding them as literals in the workflow makes it harder to rotate (requires a PR vs a repo-secret change). Moving them to the workflow-level env: block or to repo variables (vars.APPLE_TEAM_ID) would keep them in one place and make rotation easier without needing a code change.

  • [NIT-4] build/package/linux/index.sh:643abuild-sign and apk-tools installation uses a single apt-get install ... || apt-get install ... fallback pattern that silently skips the apk tooling if it's unavailable, then the downstream APK index block re-checks with command -v abuild-sign. This is correct but the warning message at line 686 says "skipping apk index (deb/rpm done)" without an explicit exit-0 signal. If abuild-sign is absent the workflow continues silently — which is the intended behaviour for pre-release, but a real release with IS_PRERELEASE == false skips the APK index without any error. Consider checking APK_KEY_PRIVATE is set AND abuild-sign is available at the top of the function, and exit 1 on a real release if the tooling is missing.

Verification log

  • gh auth status → authenticated as padak on github.com
  • gh pr view 405 --json title,body,files,additions,deletions,baseRefName,headRefName,labels,state → 15 files, +898/-1, state=OPEN ✓
  • git rev-parse --abbrev-ref HEAD after gh pr checkout 405 --detach → detached at 2b7a6af
  • CONTRIBUTING.md Plugin synchronization map read ✓ — no new CLI commands in diff; plugin sync map not applicable; confirmed via grep -E '@.*_app\.command' /tmp/kbagent-pr-405.diff → empty
  • 3-layer compliance (grep typer/click/formatter/httpx in wrong layer) → no hits; PR touches only build/, .github/, docs/, and .gitignore — no Python source layer touched
  • make check (with uv sync --extra server first) → 4124 passed, 8 skipped, exit 0 ✓
  • grep -E 'APPLE_TEAM_ID|46P6KJ65M2' diff → hardcoded at release-kbagent.yml:203 and sign_notarize.sh comment/example; non-secret public identifiers ✓ (NIT-3)
  • grep 'DEB_KEY_PUBLIC' diff → appears in ADR secrets table (line 958) but NOT in any workflow job env or script; index.sh:621 explains it's derived — confirmed NB-3
  • ADR line 908 claims "macOS amd64/arm64"; freeze matrix line 168 is arm64 only — confirmed NB-2
  • grep '^+permissions:' diff → top-level contents: write + id-token: write at line 74-76 — confirmed NB-1; existing release.yml also uses top-level permissions (same pattern, same risk)
  • Conventional commit prefix: feat(ci): — CI-only changes are often chore(ci):, but feat: is acceptable for new infrastructure capability that delivers user-visible install paths; no rule violation
  • ADR status Proposed at docs/adr/0003-release-distribution-cicd.md:5; ADR 0001 and 0002 both say Accepted in this repo — confirmed NIT-1
  • PyInstaller --collect-all keboola_agent_cli correctness: uv build --wheel runs the hatch build hook which populates src/keboola_agent_cli/_ui_dist/ in-place; PyInstaller then collects it. Confirmed by reading scripts/hatch_build.py_ui_dist/ exists in the source tree after the hook runs ✓
  • nfpm hash (0a188f8b...) at package-linux step and jsign hash (05ca18d4...) at windows/sign.sh:815 are verified with sha256sum -c - before execution ✓
  • wingetcreate Authenticode check (Get-AuthenticodeSignature asserts Status -eq Valid and Subject -match Microsoft) before execution ✓
  • Version regex tested locally: handles 0.44.0, 0.44.0b1, 0.44.0rc1, 0.44.0.dev1 correctly ✓
  • Behavior verification: no CLI command changes in this PR; runtime behavior unchanged; no reproduction needed

Open questions for the author

  • The test-install job (line 392) has no explicit if: condition; it inherits skip-propagation from publish-s3 and homebrew. Is this intentional, or would an explicit if: startsWith(github.ref, 'refs/tags/') && needs.version.outputs.IS_PRERELEASE == 'false' be clearer to future maintainers who wonder why test-install never appears in dry-run workflow dispatch runs?

  • For the Windows signing step (windows/sign.sh), KEYVAULT="${AZURE_KEYVAULT_NAME:-kbc-cli-code-signing}" and ALIAS="${AZURE_CERT_ALIAS:-codesigning}" default to production Key Vault names. If a dev ever runs this script locally with the secrets env populated and forgets to override AZURE_KEYVAULT_NAME, they'll hit the production vault. Was this considered? (The script itself requires all three WINDOWS_SIGNING_* secrets to be set and is only invoked from CI, so the practical risk is low — more of a "least-surprise" question.)

Default the workflow token to contents:read and grant elevated scopes only
to the jobs that actually need them, per GitHub security-hardening guidance:

  - pypi, publish-s3: contents:read + id-token:write (OIDC for PyPI / AWS)
  - github-release:   contents:write (softprops/action-gh-release)

version, gate, freeze, package-linux and the external-PAT jobs (homebrew,
chocolatey, winget) and test-install stay read-only. Previously every job
inherited the workflow-level contents:write + id-token:write, so jobs that
never publish (e.g. version, gate, freeze) ran with a token that could push
to the repo and mint OIDC credentials.
@padak

padak commented Jun 18, 2026

Copy link
Copy Markdown
Member

Pushed 16765c5 to address NB-1 from the automated review (workflow-level id-token: write + contents: write granted to every job).

The workflow token now defaults to contents: read, and only the jobs that genuinely publish get an elevated scope:

Job Scope Why
pypi, publish-s3 contents: read + id-token: write OIDC for PyPI Trusted Publishing / AWS configure-aws-credentials
github-release contents: write softprops/action-gh-release creates the Release
everything else (version, gate, freeze, package-linux, homebrew, chocolatey, winget, test-install) contents: read (inherited) no GITHUB_TOKEN-scoped publish (external pushes use their own PATs)

Note: upload-artifact/download-artifact@v4 don't need contents: write — they use the Actions runtime token, not GITHUB_TOKEN permissions. YAML validated with yaml.safe_load. Feel free to squash this into your packaging commit on merge.

…IT-1)

- macOS build matrix is arm64-only (Apple Silicon). The ADR said "macOS
  amd64/arm64" but the freeze matrix has no Intel leg; Intel Macs fall
  back to `uv tool install`. (NB-2)
- Drop DEB_KEY_PUBLIC from the secrets table: the apt keyring is exported
  inline from DEB_KEY_PRIVATE by index.sh and no DEB_KEY_PUBLIC is read
  anywhere in the scripts or workflow. RPM_KEY_PUBLIC stays — publish-s3
  does pass it. (NB-3)
- Status Proposed -> Accepted, matching the ADR 0001/0002 convention. (NIT-1)
@padak

padak commented Jun 18, 2026

Copy link
Copy Markdown
Member

Pushed c10ab06 addressing NB-2, NB-3 and NIT-1 (all ADR-only, no workflow/script behavior change):

  • NB-2 — the matrix prose now reads macOS arm64 with an inline note that it's Apple Silicon only and Intel Macs fall back to uv tool install, matching the freeze matrix (which has no Intel leg by design).
  • NB-3 — dropped DEB_KEY_PUBLIC from the secrets table with a note that the apt keyring is exported inline from DEB_KEY_PRIVATE by index.sh. Kept RPM_KEY_PUBLICpublish-s3 does pass that one.
  • NIT-1 — Status ProposedAccepted, matching ADR 0001/0002.

Remaining nits left for your call (policy / behavior trade-offs, not auto-applied): NIT-2 SHA-pin cpina/github-action-push-to-another-repository (write-scoped PAT), NIT-3 move the hardcoded Apple ID/Team ID to vars./workflow env:, NIT-4 make index.sh fail a real (non-prerelease) build if APK signing tooling is missing instead of skipping silently.

- NIT-2: SHA-pin cpina/github-action-push-to-another-repository to 07c4d7b
  (v1.7.2). It receives the write-scoped HOMEBREW_TAP_TOKEN, so a mutable
  tag re-point would be a supply-chain foothold.
- NIT-3: move the non-secret Apple identifiers (APPLE_ACCOUNT_USERNAME,
  APPLE_TEAM_ID) from the freeze step env to the workflow-level env so
  rotation is a one-line change; the macOS sign step inherits them.
- NIT-4: index.sh now fails loudly (exit 1) when APK_KEY_PRIVATE is set but
  abuild-sign/apk is unavailable, instead of silently skipping the apk index
  on a real release. Mirrors the existing DEB_KEY_PRIVATE guard; an unset
  APK_KEY_PRIVATE stays an explicit opt-out (warning + skip).
@padak

padak commented Jun 18, 2026

Copy link
Copy Markdown
Member

Pushed 9e08ad7 addressing the remaining nits NIT-2, NIT-3, NIT-4:

  • NIT-2 — SHA-pinned cpina/github-action-push-to-another-repository to 07c4d7b (v1.7.2 in a trailing comment). It's the one third-party action holding a write-scoped PAT (HOMEBREW_TAP_TOKEN), so a re-pointed mutable tag would be a real foothold. The other third-party actions (softprops, pypa, aws-actions) are left on version tags — pin those too if you want to go all-in on SHA pinning.
  • NIT-3 — moved APPLE_ACCOUNT_USERNAME / APPLE_TEAM_ID (both public, non-secret) from the freeze step env to the workflow-level env:; the macOS sign step inherits them, so rotation is now a one-line change.
  • NIT-4index.sh now fails loudly (exit 1) when APK_KEY_PRIVATE is set but abuild-sign/apk is unavailable, instead of silently shipping a real release with no apk index. This mirrors your existing DEB_KEY_PRIVATE guard at the top of the script. An unset APK_KEY_PRIVATE stays an explicit opt-out (warning + skip), so nothing changes if apk signing isn't configured.

Validated: workflow yaml.safe_load OK, bash -n index.sh OK. All review findings (NB-1/2/3 + NIT-1/2/3/4) are now addressed across 16765c5, c10ab06, 9e08ad7 — squash as you see fit on merge.

@padak padak left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All findings from the automated review pass are now addressed on this branch:

  • NB-1 — per-job GITHUB_TOKEN scoping (least privilege) — 16765c5
  • NB-2 / NB-3 / NIT-1 — ADR drift (macOS arm64-only, drop unused DEB_KEY_PUBLIC, status Accepted) — c10ab06
  • NIT-2 / NIT-3 / NIT-4cpina action SHA-pinned, Apple identifiers moved to workflow-level env, index.sh fails loudly when APK_KEY_PRIVATE is set but apk tooling is missing — 9e08ad7

Workflow YAML and index.sh validated locally (yaml.safe_load, bash -n). Real jobs, correct tag gating, supply-chain-conscious. Approving. Squash as preferred on merge.

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.

4 participants