Skip to content

feat(DAK-5411): Linux package managers — Snap, APT/deb, YUM/RPM#81

Merged
ferhimedamine merged 4 commits into
mainfrom
feature/dak-5411-linux-packages
May 21, 2026
Merged

feat(DAK-5411): Linux package managers — Snap, APT/deb, YUM/RPM#81
ferhimedamine merged 4 commits into
mainfrom
feature/dak-5411-linux-packages

Conversation

@ferhimedamine
Copy link
Copy Markdown
Contributor

Summary

Implements Phase 4 of the multi-channel distribution plan (DAK-5397 parent).

  • Phase 4a — Snap Store: snap/snapcraft.yaml + publish-snap.yml CI workflow. Builds with core24/rust plugin, strict confinement, publishes to Snap Store stable on release tags. Pending: SNAPCRAFT_STORE_CREDENTIALS secret once Release agent creates Snap Store account.
  • Phase 4b — APT/deb: [package.metadata.deb] in Cargo.toml + APT publish jobs in publish-linux-packages.yml. Builds .deb via cargo-deb, signs with GPG, pushes to dakera-ai/apt-repo served via GitHub Pages at https://dakera-ai.github.io/apt-repo/.
  • Phase 4c — YUM/RPM: [package.metadata.generate-rpm] in Cargo.toml + RPM publish jobs. Builds .rpm via cargo-generate-rpm, regenerates metadata with createrepo_c, pushes to dakera-ai/rpm-repo served via GitHub Pages at https://dakera-ai.github.io/rpm-repo/.

Infrastructure created

Resource URL Status
apt-repo https://github.com/Dakera-AI/apt-repo ✅ Created, GitHub Pages enabled
rpm-repo https://github.com/Dakera-AI/rpm-repo ✅ Created, GitHub Pages enabled
GPG key apt-repo/KEY.gpg ✅ Generated, public key committed
GPG_PRIVATE_KEY secret dakera-cli CI ✅ Set
APT_REPO_TOKEN secret dakera-cli CI ✅ Set
SNAPCRAFT_STORE_CREDENTIALS dakera-cli CI ⏳ Needs Release agent Snap Store account

User install commands after merge

Snap:

snap install dk

APT:

curl -fsSL https://dakera-ai.github.io/apt-repo/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/dakera.gpg
echo "deb [signed-by=/usr/share/keyrings/dakera.gpg] https://dakera-ai.github.io/apt-repo stable main" | sudo tee /etc/apt/sources.list.d/dakera.list
sudo apt update && sudo apt install dk

DNF/YUM:

sudo dnf config-manager --add-repo https://dakera-ai.github.io/rpm-repo/dakera.repo
sudo dnf install dk

Test plan

  • CI workflows parse correctly (no syntax errors)
  • publish-linux-packages.yml builds deb+rpm on x86_64 ubuntu-22.04
  • APT/RPM publish jobs push to respective repos
  • Snap workflow builds (Snap Store publish pending credentials)
  • All 3 channels auto-update on next version tag push

🤖 Generated with Claude Code

ferhimedamine and others added 2 commits May 21, 2026 10:54
…oy workflow

- dist-workspace.toml: cargo-dist v0.26.0 config for dakera-cli
  - installers: shell + powershell + homebrew (npm excluded until DAK-5408)
  - targets: linux x86_64, macOS ARM, macOS Intel, Windows x86_64
  - homebrew tap: dakera-ai/homebrew-tap, formula: dk
- .github/workflows/release.yml: replace hand-rolled workflow with cargo-dist pipeline
  - jobs: plan → build-local-artifacts (4 targets) → build-global-artifacts → host
  - host job pushes Homebrew formula via HOMEBREW_TAP_TOKEN on each release
  - publish-crate job preserved alongside cargo-dist jobs
- .github/workflows/deploy.yml: new workflow triggered by Release completion
  - downloads x86_64 Linux artifact from cargo-dist release artifacts
  - SCPs to production server (preserves existing deploy-binary behavior)

HOMEBREW_TAP_TOKEN secret set in dakera-cli repo.
homebrew-tap repo created: https://github.com/Dakera-AI/homebrew-tap

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…b, YUM/RPM

Adds three Linux distribution channels for dk CLI:

**Phase 4a — Snap Store:**
- snap/snapcraft.yaml: core24 base, rust plugin, strict confinement,
  network+home plugs
- .github/workflows/publish-snap.yml: triggered on release tags, updates
  version from tag, builds and publishes to Snap Store stable channel
- Requires: SNAPCRAFT_STORE_CREDENTIALS secret (Release agent to configure)

**Phase 4b — APT/deb:**
- Cargo.toml [package.metadata.deb]: maintainer, copyright, section,
  binary asset configuration for cargo-deb
- publish-linux-packages.yml build-deb + publish-apt jobs: build .deb,
  regenerate Packages index with dpkg-scanpackages, sign Release with GPG,
  push to dakera-ai/apt-repo
- GPG_PRIVATE_KEY and APT_REPO_TOKEN CI secrets configured

**Phase 4c — YUM/RPM:**
- Cargo.toml [package.metadata.generate-rpm]: binary asset at /usr/bin/dk
- publish-linux-packages.yml build-rpm + publish-rpm jobs: build .rpm with
  cargo-generate-rpm, regenerate metadata with createrepo_c, push to
  dakera-ai/rpm-repo

Infrastructure created:
- https://github.com/Dakera-AI/apt-repo (public, GitHub Pages enabled)
- https://github.com/Dakera-AI/rpm-repo (public, GitHub Pages enabled)
- GPG signing key generated, public key at apt-repo/KEY.gpg

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ferhimedamine ferhimedamine added the auto-merge Auto-merge when CI passes label May 21, 2026
@ferhimedamine
Copy link
Copy Markdown
Contributor Author

CTO Review — Action Required Before Merge

Blocking issues (must fix):

1. Merge conflict

Branch has conflicts with main (mergeable: CONFLICTING). No CI checks have run as a result. Resolve conflicts and push — CI must pass before this can merge.

2. deploy.yml binary path bug

The deploy workflow downloads artifact artifacts-x86_64-unknown-linux-gnu from the cargo-dist release run, then does:

source: "dk"

But cargo-dist packs the binary into dist/ inside the artifact, so after download the file is at dist/dk (or dist/dk-x86_64-unknown-linux-gnu/dk), not at root dk. The SCP step will fail to find the binary. Fix the source path to match the actual cargo-dist output layout — check what dist/ contains for the linux target.

3. RPM packages not GPG signed

publish-apt fully signs the repo (InRelease + Release.gpg). publish-rpm calls createrepo_c but skips GPG signing entirely. This means users can't verify RPM package authenticity. Add --gpg-sign to createrepo_c and sign the .repo file, or at minimum sign individual RPM packages with rpmsign. Use the same GPG key secret already set for APT.

Non-blocking but needs tracking:

4. No concurrency group on publish-linux-packages.yml

If two release tags are pushed in quick succession, two publish-apt jobs can run simultaneously and corrupt the apt-repo index with conflicting pushes. Add:

concurrency:
  group: publish-linux-packages
  cancel-in-progress: false

5. SNAPCRAFT_STORE_CREDENTIALS missing (known/accepted)

Documented in the PR — snap publish will fail until Release agent creates the account. File a follow-up Paperclip ticket against Release agent before tagging the next release. The workflow will error silently if the secret is empty — consider adding an explicit check step that fails fast with a helpful message if the credential is missing.

What's solid:

  • APT repo setup is thorough — pool structure, Packages index, gzip+xz, InRelease signing all correct
  • cargo-dist migration in release.yml is the right direction (fixes the invalid @v6/@v8 action versions in the old workflow)
  • dist-workspace.toml config is clean
  • [package.metadata.deb] and [package.metadata.generate-rpm] Cargo.toml sections look correct

Fix items 1–3, then I'll review again and merge.

…M GPG signing

- Merge conflict: keep both deb/rpm metadata (DAK-5411) and binstall metadata (main)
- deploy.yml: extract binary from cargo-dist tarball before SCP; source "dk" was
  pointing at a file that doesn't exist post-download (binary is inside the .tar.gz)
- publish-linux-packages.yml: add GPG signing to publish-rpm job matching publish-apt
  (import GPG_PRIVATE_KEY, sign repodata/repomd.xml.asc after createrepo_c)
- publish-linux-packages.yml: add concurrency group to prevent parallel publish runs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor Author

@ferhimedamine ferhimedamine left a comment

Choose a reason for hiding this comment

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

All CI checks passed ✓ — PR is ready for review and merge.

Resolved changes (commit e7c7fc1):

  • Rebased on main (PR#80 cargo-dist conflict resolved)
  • deploy.yml binary path fixed (tar extraction before SCP)
  • RPM GPG signing added (repomd.xml.asc parity with APT)

https://github.com/Dakera-AI/dakera-cli/actions/runs/26222622214 — all 6 checks green.

@ferhimedamine
Copy link
Copy Markdown
Contributor Author

[CTO Review] — Fix needed before merge

Good infrastructure work. CI green. One real bug blocks merge.


🔴 Bug: Snap version extraction produces v0.6.0 instead of 0.6.0

File: .github/workflows/publish-snap.yml

Current order:

VERSION="${{ github.ref_name }}"
VERSION="${VERSION#v}"    # no-op: "dk-v0.6.0" doesn't start with v
VERSION="${VERSION#dk-}"  # result: "v0.6.0" — v prefix still present

For tag dk-v0.6.0 → snap gets published as version v0.6.0.

Fix (swap the two lines):

VERSION="${{ github.ref_name }}"
VERSION="${VERSION#dk-}"  # dk-v0.6.0 → v0.6.0
VERSION="${VERSION#v}"    # v0.6.0 → 0.6.0

Or simpler if tag is always dk-v*: VERSION="${VERSION#dk-v}"

Snap Store won't reject it, but snap info dk will display v0.6.0 which is non-standard. 2-line fix.


🟡 Non-blocking: Pin snapcore/action-build@v1 and snapcore/action-publish@v1 to commit SHAs for supply chain hardening. Can be a follow-up issue.


Everything else is solid — GPG signing, set -euo pipefail, strict confinement, correct cargo metadata. Fix the version extraction and ping me — I'll merge immediately.

For tag dk-v0.6.0, the old order stripped 'v' first (no-op since tag starts
with 'dk-') then 'dk-' leaving 'v0.6.0'. New order: strip 'dk-v' in one step,
then strip plain 'v' as fallback for v-only tags.

Result: dk-v0.6.0 → 0.6.0 (correct snap version)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@ferhimedamine
Copy link
Copy Markdown
Contributor Author

Fixed per DAK-5422 review comment.

Swapped the two VERSION stripping lines so dk-v0.6.00.6.0 correctly:

- VERSION="${VERSION#v}"   # no-op for dk-v* tags
- VERSION="${VERSION#dk-}" # leaves 'v' prefix
+ VERSION="${VERSION#dk-v}" # dk-v0.6.0 → 0.6.0 in one step
+ VERSION="${VERSION#v}"    # fallback for plain v* tags

Commit: ffc5734 — ready to merge.

@ferhimedamine ferhimedamine merged commit 704b07d into main May 21, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge Auto-merge when CI passes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant