Skip to content

Add Nix flake support with source build, prebuilt, and desktop outputs - #5

Open
levonk wants to merge 35 commits into
acryldev:mainfrom
levonk:feature/nix-flake-support
Open

levonk wants to merge 35 commits into
acryldev:mainfrom
levonk:feature/nix-flake-support

Conversation

@levonk

@levonk levonk commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add flake.nix with #acryl (TUI from source, also #default), #prebuilt (prebuilt CLI release tarball, v0.1.36), #acryl-desktop (Electron from source), and devShells.default
  • #prebuilt is conditionally exposed only on platforms with a release asset (x86_64-linux, aarch64-linux, aarch64-darwin). v0.1.36 does not ship a darwin-x64 CLI tarball, so #prebuilt is not available on x86_64-darwin — use #default or #acryl there.
  • Add devbox.json + devbox.lock for reproducible development environments
  • Add .github/workflows/nix.yml — CI builds all outputs on x86_64-linux, aarch64-linux, aarch64-darwin, and x86_64-darwin using macos-26/macos-26-intel runners
  • Add .github/workflows/nix-release.yml — daily hash automation that detects when flake.nix lags behind the latest GitHub release, prefetches new SRI hashes, and opens a PR
  • Update README.md, README.en.md, README.zh.md with Nix and Devbox install instructions
  • Update .gitignore with /result, /result-*, and .devbox/

Platform scope

The project's CI matrix is Linux-only, but the project ships release binaries for all four Nix target systems (x86_64-linux, aarch64-linux, aarch64-darwin, x86_64-darwin). This flake supports all four systems. The detect-platform-scope.sh nixify detection script reports linux_only because it inspects .github/workflows/ CI matrices, but the release assets cover all four platforms. This override is noted here per the nixify skill's requirement.

Supported systems

  • x86_64-linux — source build + prebuilt
  • aarch64-linux — source build + prebuilt
  • aarch64-darwin — source build + prebuilt
  • x86_64-darwin — source build only (via nixpkgs-26.05-darwin legacy pin; no prebuilt tarball available for this platform)

Relationship to nixpkgs

This project is not currently in nixpkgs. If there is interest in adding it, the flake's #acryl source build derivation could serve as the basis for a nixpkgs package expression.

Test plan

  • nix flake check --no-build passes on all systems
  • nix build .#acryl succeeds on all systems
  • nix build .#acryl-desktop succeeds on all systems
  • nix build .#prebuilt succeeds on x86_64-linux, aarch64-linux, aarch64-darwin
  • nix run .#acryl -- --help works
  • nix run .#prebuilt -- --help works (where available)
  • nix run .#acryl-desktop -- --help works
  • CI workflow runs green on all four systems
  • Hash automation workflow detects version lag and opens a PR

@musichen

musichen commented Sep 2, 2026

Copy link
Copy Markdown
Member

Hi @levonk thanks for contributing!
i'll review it once CI checks are green.

levonk added a commit to levonk/acryl that referenced this pull request Sep 2, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from aa04fae to cfa8b92 Compare September 2, 2026 20:30
@levonk
levonk marked this pull request as draft September 2, 2026 23:08
@levonk
levonk marked this pull request as ready for review September 3, 2026 03:02
@musichen

musichen commented Sep 8, 2026

Copy link
Copy Markdown
Member

Resolved the conflict against current main in 3da7171.

The resolution preserves both branches' development-log entries. I ran the repository suite in the merged worktree: 806 ACRYL tests and 274 Market tests passed. The five refreshed GitHub checks are now running; I will use those as the final merge gate.

@levonk
levonk marked this pull request as draft September 9, 2026 23:31
levonk added a commit to levonk/acryl that referenced this pull request Sep 9, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from 19fa777 to b3309f3 Compare September 9, 2026 23:31
@musichen

Copy link
Copy Markdown
Member

Thanks for the substantial work here - reviewed the flake end to end. This is real packaging engineering: the fetchPnpmDeps v4 usage, the documented nodeLinker override, the ESBUILD_BINARY_PATH substitution, autoPatchelf + musl handling for koffi, SHA-pinned actions with PR guards - all correct. The README.i18n.yaml hash-record update was a nice touch too.

Three blockers before merge:

  1. The branch is ~154 commits behind main and conflicts - needs a rebase.
  2. The pnpmDeps fixed-output hash is stale against main's current pnpm-lock.yaml - all four builds currently fail with hash mismatch (your fork's latest Nix run shows it). Refresh the hash after rebasing. Heads-up: every future pnpm-lock.yaml change invalidates it - are you up for owning flake maintenance as our Nix maintainer?
  3. x86_64-darwin can't install Determinate Nix on the macos-13 runner anymore (Intent to Ship: Dropping support for macOS Intel (x86_64-darwin) hosts DeterminateSystems/nix-src#224) - either cross-build that target from an arm64 runner or drop it from CI and keep the derivation for local Intel builders.

Would love one fully green 4-system run on the branch before merging. Happy to review the follow-up.

musichen pushed a commit to levonk/acryl that referenced this pull request Sep 11, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@musichen
musichen force-pushed the feature/nix-flake-support branch from b3309f3 to fe21243 Compare September 11, 2026 17:06
levonk added a commit to levonk/acryl that referenced this pull request Sep 12, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from 7d21d18 to e6868a4 Compare September 12, 2026 01:01
levonk added a commit to levonk/acryl that referenced this pull request Sep 12, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from e6868a4 to 6cb9194 Compare September 12, 2026 19:48
levonk added a commit to levonk/acryl that referenced this pull request Sep 12, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from 804a930 to 0ba0402 Compare September 12, 2026 23:47
levonk added a commit to levonk/acryl that referenced this pull request Sep 13, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from 0ba0402 to 5369acf Compare September 13, 2026 00:28
Add Nix flake support targeting the acryl-tui terminal client. The
flake uses nixpkgs' modern PNPM hooks (fetchPnpmDeps, pnpmConfigHook)
with pnpm_11 and fetcherVersion 4.

Key design decisions:
- Targets acryl-tui (not the Electron desktop app) as the default
  package, exposing the `acryl` binary via `nix run .#acryl`
- Uses nixpkgs-26.05-darwin legacy pin for x86_64-darwin (Intel
  macOS), since nixpkgs-unstable dropped support after 26.05
- Forces nodeLinker: hoisted in pnpm-workspace.yaml during the build
  to flatten node_modules (pnpm 11 moved this setting from .npmrc)
- Builds only the TUI dependency chain (acryl-control ->
  acryl-harness-runtime -> acryl-tui) instead of the full workspace
- Sets dontStrip and dontFixup to avoid slow strip/fixup phases on
  thousands of JS files in node_modules
- ESBUILD_BINARY_PATH points to nixpkgs esbuild to avoid the
  postinstall binary download (skipped by --ignore-scripts)

Also adds:
- devbox.json for reproducible development environment
- .github/workflows/nix.yml for CI across all 4 supported systems
- /result and /result-* to .gitignore
Document the implementation commit d6d2e46
which added Nix flake support for building acryl-tui.
Add `packages.${system}.acryl-desktop` to the flake, building the
Electron desktop app alongside the existing TUI output.

Key decisions:
- Uses nixpkgs electron (43.1.0) as the runtime instead of the npm
  electron package (which downloads a platform binary via postinstall,
  blocked by --ignore-scripts in the Nix sandbox)
- Creates a CJS shim at node_modules/electron/index.js that exports
  the nixpkgs electron path, replacing the real npm package
- Skips the generate-* build scripts (they use sharp for image
  processing) since build/ assets are already tracked in git
- Builds the full dependency chain: acryl-control ->
  acryl-harness-runtime -> dsh-community-market ->
  acryl-development-canvas -> acryl-desktop
- Refactors shared derivation attrs (pnpmDeps, preConfigure, etc.)
  into commonDerivationAttrs to avoid duplication between TUI and
  desktop derivations

Both outputs verified:
  nix run .#acryl -- --help
  nix run .#acryl-desktop -- --help
Document implementation commit 397f91034cb6a6444c6dccf6f33d06e8b10bf43b
which added the Electron desktop app as a separate Nix package output.
- SHA-pin all GitHub Actions to 40-char commit SHAs (checkout@v5,
  nix-installer-action@v22, magic-nix-cache-action@v14) instead of
  mutable @v4/@main refs — prevents supply-chain attacks
- Add if: github.event_name != 'pull_request' guard on nix run steps
  to prevent PR-controlled code from reaching GITHUB_TOKEN/OIDC
- Add path filtering to nix.yml (flake.nix, flake.lock, **/*.nix,
  pnpm-lock.yaml, etc.) so CI only fires when Nix files change
- Add nix run .#default -- --help test to CI
- Add act to devbox.json packages (required for local CI validation)
- Remove invalid nixpkgs.commit field from devbox.json (devbox 0.18
  ignores it; was set to channel name not 40-char hash)
- Add .devbox/ to .gitignore (devbox generated artifacts)
- Add Nix (Flake) and Devbox install sections to README.md,
  README.en.md, and README.zh.md
- Update bilingual-docs hash record in README.i18n.yaml

devbox.lock cannot be generated on x86_64-darwin due to devbox 0.18
hardcoding a nixpkgs commit that dropped x86_64-darwin support;
generate on aarch64-darwin or Linux.
levonk and others added 13 commits September 14, 2026 19:07
The prebuilt release tarball bundles both glibc-linked and musl-linked
native koffi addons (musl_x64/koffi.node alongside linux_x64/koffi.node).
autoPatchelfHook was only finding glibc (stdenv.cc.cc.lib), so it failed
with "could not satisfy dependency libc.musl-x86_64.so.1" on Linux.

Add pkgs.musl to buildInputs so autoPatchelf can patch both variants.
The magic-nix-cache v14 static binary for arm64-darwin fails on the
macos-14 runner with:
  dyld: Symbol not found: __ZNSt13exception_ptr31__from_native_exception_pointerEPv
  Expected in: /usr/lib/libc++.1.dylib

This is a DeterminateSystems binary incompatibility — the binary was
built against a newer libc++ than the runner ships. The build itself
never starts; the job hangs for 20 minutes then gets cancelled.

Make the cache action Linux-only. Darwin builds work without it, just
slower (no cache acceleration). The flake and builds are unaffected.
…ntel macOS runners

The macos-13 runner can no longer bootstrap Determinate Nix
(DeterminateSystems/nix-src#224), so the x86_64-darwin CI job fails
before building anything. Keep the derivation in flake.nix for local
Intel builders; restore the job via a Rosetta cross-build from
macos-14 when feasible.
… runner

Nixify skill compliance fixes after rebasing on upstream/main:

1. Update prebuilt version from v0.1.19 to v0.1.36 (latest release).
   Refresh all three per-platform SRI hashes by prefetching the
   new release assets. Remove x86_64-darwin from prebuiltAssets
   because v0.1.36 does not ship a darwin-x64 CLI tarball.

2. Make #prebuilt conditional via optionalAttrs so it is only
   exposed on platforms with a release asset (x86_64-linux,
   aarch64-linux, aarch64-darwin). On x86_64-darwin, nix run .#prebuilt
   correctly errors "package not available" instead of failing
   with a missing attribute error.

3. Add .github/workflows/nix-release.yml — daily hash automation
   workflow (scheduled lag-check template, required by nixify Step 16
   for prebuilt tarball flakes). Detects when flake.nix lags behind
   the latest GitHub release, prefetches new SRI hashes, and opens
   a PR. Uses GITHUB_TOKEN (releases are created with GITHUB_TOKEN
   via softprops/action-gh-release, so release: published would
   never fire).

4. Update aarch64-darwin CI runner from macos-14 to macos-26
   (nixify Step 16: always use the newest runner).
- Bump the Nix tag-pinning example from v0.1.19 to v0.1.36 in all three
  READMEs (README.md, README.en.md, README.zh.md).
- Note that #prebuilt is available on x86_64-linux, aarch64-linux, and
  aarch64-darwin only (v0.1.36 does not ship a darwin-x64 CLI tarball).
- Re-record the bilingual-docs blob hashes in README.i18n.yaml.
Add a development-log entry for the v0.1.36 prebuilt bump, the new
nix-release.yml hash automation workflow, the macos-26 runner update,
and the rebase onto upstream/main 0822873. Re-point the two earlier
Nix entries (acryl-desktop output and acryl-tui flake support) at
their rebased commit hashes.
The rebase onto upstream/main 227c3f9 pulled in a new pnpm-lock.yaml
(7869 lines changed) which invalidated the fetchPnpmDeps hash. Updated
to sha256-gqs/PgXIBj8+YsH/z/qIPa68XVNO7hu4eDxvShYkyxI= as reported by
the aarch64-darwin CI failure.
Main reorganized workspace packages from the root into apps/,
runtime/, plugins/, distribution/, and examples/ directories.
The flake's build and install phases still referenced the old
flat paths (acryl-cli/lib, acryl-control/lib, etc.).

- Update all source paths in build and install phases to use the
  new directory structure (apps/acryl-cli, runtime/acryl-control,
  plugins/dsh-community-market, apps/acryl-desktop).
- Add dsh-community-market to the CLI (#default) build chain —
  main added a /market command to acryl-cli that imports
  dsh-community-market, so it must be built before acryl-cli.
- Remove acryl-development-canvas from the desktop build chain —
  the package no longer exists in the workspace.
- Split installWorkspacePackage into srcDir (workspace path) and
  pkgName (node_modules name) since they now differ. Add an
  extraDirs parameter to copy non-compiled runtime assets
  (dsh-community-market reads JSON schemas from docs/schemas/
  at runtime via readFileSync relative to lib/).
@levonk
levonk force-pushed the feature/nix-flake-support branch from 5369acf to 47b5c79 Compare September 15, 2026 02:33
acryl-cli now imports dsh-community-market (added by the /market
command), but the CI workflow's 'Build workspace type providers'
step only built acryl-control and acryl-harness-runtime. The
typecheck step then fails with TS2307 for dsh-community-market.

This is a pre-existing issue on main — it was hidden because main's
CI fails earlier at the bilingual-docs gate before reaching typecheck.
The acryl-web serve test boots the web engine which loads
dsh-client-ui-brand-acryl as a profile plugin. Its lib/ directory
must exist before the test step, but the CI workflow only built
the type providers for typecheck. Add it to the same build step.

This is a pre-existing issue on main — hidden because main's CI
fails earlier at the bilingual-docs gate.
@levonk
levonk marked this pull request as ready for review September 15, 2026 19:06
@musichen

Copy link
Copy Markdown
Member

@levonk please ensure CI/CD is green
i can review as soon as it's green

@levonk
levonk marked this pull request as draft September 16, 2026 04:50
Resolve conflicts in .gitignore (union of both sides' entries) and
docs/DEVELOPMENT-LOG.md (append upstream's new entries). Follow
upstream's plugins/dsh-community-market -> plugins/cordis-plugin-market
rename in the Nix flake and ci.yml's workspace pre-build step. Re-record
README blob hashes in README.i18n.yaml for the merged bilingual pair and
refresh the stale RFC-0004 record upstream left behind. Refresh the
pnpmDeps fixed-output hash for main's current pnpm-lock.yaml.
@levonk

levonk commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

All three blockers addressed — CI is now fully green and the branch is mergeable.

  1. Rebased onto current main (merged upstream/main at 0049caf, resolving .gitignore and docs/DEVELOPMENT-LOG.md). Followed the plugins/dsh-community-marketplugins/cordis-plugin-market rename through flake.nix and ci.yml's workspace pre-build step.
  2. Refreshed the pnpmDeps fixed-output hash for main's current pnpm-lock.yaml (sha256-OGbbOnu44vOLGl1PEbghgYF6tBZXEQN8b9203LJFPK8=). Yes — happy to keep owning flake maintenance; hash bumps on lockfile changes, upstream renames, and the nix-release.yml hash automation are all mechanical follow-ups.
  3. x86_64-darwin stays out of the CI matrix (Determinate Nix installer can no longer run on the macos-13 Intel runner); the derivation remains in flake.nix for local Intel builders, as you suggested.

Also re-recorded the bilingual blob hashes for the merged README pair, and refreshed the RFC-0004 i18n record that was stale on main itself.

Green run: Typecheck, test, and build + Nix builds on x86_64-linux, aarch64-linux, aarch64-darwin all pass.

@levonk
levonk marked this pull request as ready for review September 17, 2026 22:10
@levonk
levonk marked this pull request as draft September 17, 2026 22:12
…staller

The job was dropped after the Determinate installer failed on the
deprecated macos-13 image. The actual constraint is narrower:
Determinate stopped shipping Intel *host* builds in Nov 2025
(DeterminateSystems/nix-src#224), but GitHub still provides Intel
runners and upstream Nix installs fine on them. Run the leg on
macos-26-intel (the current Intel label, GA Feb 2026) using
cachix/install-nix-action with flakes enabled explicitly; other legs
keep the Determinate installer.
@levonk

levonk commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Correction to my previous update on blocker 3: macos-13 was the wrong image all along — it's a deprecated runner label. The current Intel macOS runner is macos-26-intel (GA since Feb 2026). Determinate did drop Intel host builds (nix-src#224), so that leg installs upstream Nix via cachix/install-nix-action (SHA-pinned v31.11.1) instead of the Determinate installer; the other three legs are unchanged.

I'd rather keep the x86_64-darwin CI coverage than drop it: the flake's nixpkgs-26.05-darwin legacy pin is the only path to a current-version install for Intel Mac users now that nixpkgs-unstable no longer builds there, and CI is what catches that pin rotting. One follow-up fix in the same push: #prebuilt is skipped on systems with no release asset (v0.1.36 ships no darwin-x64 tarball), which is what the Intel leg was actually tripping on.

Fully green run now includes all four systems: x86_64-linux, aarch64-linux, aarch64-darwin, x86_64-darwin (13m50s), plus typecheck/test/build.

@levonk
levonk marked this pull request as ready for review September 18, 2026 17:08
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.

2 participants