- JavaScript 93.8%
- Nix 6.2%
|
All checks were successful
Smoke / smoke (push) Successful in 28s
attic use writes both substituter + netrc with token, giving Nix authenticated pull access. Replaces our manual nix.conf writing which lacked auth and caused HTTP 401 on private cache pulls. Drops the public-key input — attic fetches it from the server. Drops lib/nixconf.js and NIX_USER_CONF_FILES plumbing. |
||
|---|---|---|
| .forgejo/workflows | ||
| docs/superpowers | ||
| fixtures/test-flake | ||
| lib | ||
| test | ||
| .envrc | ||
| .gitignore | ||
| action.yml | ||
| flake.lock | ||
| flake.nix | ||
| main.js | ||
| package.json | ||
| post.js | ||
| README.md | ||
setup-attic
A Forgejo Action that configures a CI job to pull from and push to a self-hosted attic Nix binary cache. One step in your workflow; both phases handled automatically via Forgejo's main/post action hooks.
Usage
- uses: actions/checkout@v6
- uses: matt/setup-attic@v1
with:
endpoint: https://cache.example.com
cache: my-cache
token: ${{ secrets.ATTIC_TOKEN }}
flake-refs: .#my-package
- run: nix build .#my-package --no-link
The main phase installs the attic client, wires the cache up as a Nix substituter (so your builds pull from it), and authenticates. The post phase resolves paths:/flake-refs: to realised store paths and pushes them — skipping anything that wasn't actually built, with no error.
Inputs
| Name | Required | Description |
|---|---|---|
endpoint |
yes | Attic server base URL, e.g. https://cache.example.com. |
cache |
yes | Cache name on the server, e.g. my-cache. |
token |
yes | Attic JWT, scoped to at least push on the target cache. Always source from a secret. |
paths |
no | Newline-separated list of store paths or symlinks (like ./result) to push. |
flake-refs |
no | Newline-separated list of flake references (like .#my-package) to resolve and push at job end. |
fail-on-push-error |
no | true to fail the job on push failure. Default false — cache is an optimization, main work already succeeded. |
At least one of paths or flake-refs must be non-empty.
Multiple entries, newline-separated:
with:
flake-refs: |
.#foo
.#bar
.#baz
Obtaining a token
On the attic server:
attic make-token --sub ci --validity 90d --push my-cache
Copy the output into your repo's secrets as ATTIC_TOKEN (or whatever name you reference in the workflow). Refer to attic's docs for finer-grained token options.
How it works
- Node action with
main:andpost:hooks, following the same pattern asactions/cache. One step in your workflow; thepostphase fires automatically after subsequent steps finish. - Zero npm dependencies. Pure Node stdlib +
child_process. Nodist/bundle. - Attic client is realised on-demand via
nix run nixpkgs#attic-client. First invocation pays the build cost; subsequent runs on the same host are a cache lookup. - Server name in the attic config is deterministically derived from
<endpoint-hostname-slug>-<cache>, so you can use this action multiple times in one job pointing at different caches (or different servers) without collisions. - Missing paths (a declared flake-ref that wasn't built, a
./resultsymlink that doesn't exist) are skipped with a warning rather than failing the job. Mirrorsactions/cache's behavior.
Security
- Token is a secret. Always source
token:from${{ secrets.* }}. Never hardcode. - No cross-job leakage. Forgejo's runner creates a fresh container per job (
ReuseContainers: false). Credentials written to~/.config/attic/config.tomldie with the container. - Within-job exposure. Other actions running in the same job can read the attic credentials file while the job is in progress. If you compose this action with untrusted third-party actions in the same workflow, be aware.
License
MIT.