Compare commits

..

13 Commits
v0.1.4 ... main

Author SHA1 Message Date
22c2bb1406 Make build 2024-06-16 21:26:31 -06:00
8e8ff90bd6 Use full path when accessing attic 2024-06-16 20:52:16 -06:00
Paul Zinselmeyer
5619ef4781
feat: skip installation of attic when installed (#21) 2024-05-25 08:29:36 +00:00
dependabot[bot]
37f74ba5fa
chore(deps): bump pnpm/action-setup from 2 to 3 (#19)
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 2 to 3.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v2...v3)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-23 03:37:47 -04:00
dependabot[bot]
6cfb1137df
chore(deps): bump DeterminateSystems/nix-installer-action from 7 to 9 (#15)
Bumps [DeterminateSystems/nix-installer-action](https://github.com/determinatesystems/nix-installer-action) from 7 to 9.
- [Release notes](https://github.com/determinatesystems/nix-installer-action/releases)
- [Commits](https://github.com/determinatesystems/nix-installer-action/compare/v7...v9)

---
updated-dependencies:
- dependency-name: DeterminateSystems/nix-installer-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-23 03:37:03 -04:00
Ryan
f75ac4b827
fix: support nix >= 2.19 (#18)
* fix: TypeError when pushing

* fix: compatibility with Nix 2.18
2024-01-07 22:00:22 +00:00
seth
6689ac7697
push: don't report failure on error (#16) 2023-12-14 11:12:23 +00:00
dependabot[bot]
4698511c85
chore(deps): bump DeterminateSystems/nix-installer-action from 5 to 7 (#13)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-08 14:21:59 +00:00
seth
7f0e30fedd
chore: misc cleanups for flake and ci (#12) 2023-11-08 14:21:46 +00:00
Ryan Cao
40fa276ac0
chore: use Node v20 for nvm/fnm 2023-10-25 23:20:59 +08:00
dependabot[bot]
fae7bd1d97
chore(deps): bump actions/setup-node from 3 to 4 (#11)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 03:41:22 +00:00
dependabot[bot]
aa6bedf232
chore(deps): bump DeterminateSystems/nix-installer-action from 4 to 5 (#9) 2023-10-10 07:19:24 +08:00
Ryan Cao
6870271f1d
feat!: node18 2023-09-15 15:37:51 +08:00
22 changed files with 739 additions and 26 deletions

7
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

31
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Release
on:
release:
types: [published, edited]
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.release.tag_name }}
- uses: pnpm/action-setup@v3
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- name: Build
run: pnpm install && pnpm build
- uses: JasonEtco/build-and-tag-action@v2
env:
GITHUB_TOKEN: ${{ github.token }}

41
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: "Test"
on:
push:
branches: ["main"]
workflow_call:
workflow_dispatch:
jobs:
test-cache:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- name: Build
run: pnpm install && pnpm build
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v9
- name: Setup Attic Cache
uses: ./
with:
endpoint: ${{ secrets.ATTIC_ENDPOINT }}
cache: ${{ secrets.ATTIC_CACHE }}
token: ${{ secrets.ATTIC_TOKEN }}
- name: Build Nix Package
run: nix-build test.nix

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.DS_Store
node_modules/
# nix
.direnv/
.envrc
result*

1
.node-version Normal file
View File

@ -0,0 +1 @@
20

4
.prettierignore Normal file
View File

@ -0,0 +1,4 @@
.direnv/
dist/
pnpm-lock.yaml

4
.prettierrc Normal file
View File

@ -0,0 +1,4 @@
{
"useTabs": true,
"printWidth": 120
}

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Ryan Cao
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

44
README.md Normal file
View File

@ -0,0 +1,44 @@
# attic-action
Cache Nix derivations with [Attic](https://github.com/zhaofengli/attic).
## Usage
Configure your attic instance with an endpoint, a cache, and a token that can read from and write to the cache. Then, add this step to a workflow job after Nix is installed:
```yaml
- name: Setup Attic cache
uses: ryanccn/attic-action@v0
with:
endpoint: ${{ secrets.ATTIC_ENDPOINT }}
cache: ${{ secrets.ATTIC_CACHE }}
token: ${{ secrets.ATTIC_TOKEN }}
```
## Inputs
### `endpoint`
The Attic endpoint. This is the URL without the cache name.
### `cache`
The name of the Attic cache.
### `token`
The authorization token to provide to Attic (**optional**).
### `skip-push`
Disable pushing new derivations to the cache automatically at the end of the job (**default is false**).
This requires you to invoke `attic push <cache>` with the paths you want to push to the cache manually.
## Outputs
None
## License
MIT

View File

@ -24,6 +24,6 @@ inputs:
required: false required: false
runs: runs:
using: "node16" using: "node20"
main: "dist/index.js" main: "dist/index.js"
post: "dist/index.js" post: "dist/index.js"

30
dist/index.js vendored

File diff suppressed because one or more lines are too long

26
flake.lock generated Normal file
View File

@ -0,0 +1,26 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1689850295,
"narHash": "sha256-fUYf6WdQlhd2H+3aR8jST5dhFH1d0eE22aes8fNIfyk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5df4d78d54f7a34e9ea1f84a22b4fd9baebc68d0",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

30
flake.nix Normal file
View File

@ -0,0 +1,30 @@
{
description = "Github Action for caching Nix derivations with attic";
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
};
outputs = {nixpkgs, ...}: let
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forAllSystems = fn: nixpkgs.lib.genAttrs systems (system: fn nixpkgs.legacyPackages.${system});
in {
devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
packages = with pkgs; [
actionlint
nodejs_20
(nodePackages_latest.pnpm.override {nodejs = nodejs_20;})
];
};
});
formatter = forAllSystems (p: p.alejandra);
};
}

23
package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "@ryanccn/attic-action",
"main": "dist/index.js",
"description": "Cache Nix derivations with attic",
"scripts": {
"build": "esbuild src/index.ts --outdir=dist --platform=node --format=cjs --bundle --minify-whitespace --minify-syntax",
"format": "prettier --write ."
},
"author": "Ryan Cao <hello@ryanccn.dev>",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"just-split": "^3.2.0"
},
"devDependencies": {
"@types/node": "^16.18.38",
"esbuild": "^0.18.14",
"prettier": "3.0.0",
"typescript": "^5.1.6"
},
"packageManager": "pnpm@8.7.5"
}

313
pnpm-lock.yaml generated Normal file
View File

@ -0,0 +1,313 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
'@actions/core':
specifier: ^1.10.0
version: 1.10.0
'@actions/exec':
specifier: ^1.1.1
version: 1.1.1
just-split:
specifier: ^3.2.0
version: 3.2.0
devDependencies:
'@types/node':
specifier: ^16.18.38
version: 16.18.38
esbuild:
specifier: ^0.18.14
version: 0.18.14
prettier:
specifier: 3.0.0
version: 3.0.0
typescript:
specifier: ^5.1.6
version: 5.1.6
packages:
/@actions/core@1.10.0:
resolution: {integrity: sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==}
dependencies:
'@actions/http-client': 2.1.0
uuid: 8.3.2
dev: false
/@actions/exec@1.1.1:
resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==}
dependencies:
'@actions/io': 1.1.3
dev: false
/@actions/http-client@2.1.0:
resolution: {integrity: sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==}
dependencies:
tunnel: 0.0.6
dev: false
/@actions/io@1.1.3:
resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==}
dev: false
/@esbuild/android-arm64@0.18.14:
resolution: {integrity: sha512-rZ2v+Luba5/3D6l8kofWgTnqE+qsC/L5MleKIKFyllHTKHrNBMqeRCnZI1BtRx8B24xMYxeU32iIddRQqMsOsg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-arm@0.18.14:
resolution: {integrity: sha512-blODaaL+lngG5bdK/t4qZcQvq2BBqrABmYwqPPcS5VRxrCSGHb9R/rA3fqxh7R18I7WU4KKv+NYkt22FDfalcg==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-x64@0.18.14:
resolution: {integrity: sha512-qSwh8y38QKl+1Iqg+YhvCVYlSk3dVLk9N88VO71U4FUjtiSFylMWK3Ugr8GC6eTkkP4Tc83dVppt2n8vIdlSGg==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-arm64@0.18.14:
resolution: {integrity: sha512-9Hl2D2PBeDYZiNbnRKRWuxwHa9v5ssWBBjisXFkVcSP5cZqzZRFBUWEQuqBHO4+PKx4q4wgHoWtfQ1S7rUqJ2Q==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-x64@0.18.14:
resolution: {integrity: sha512-ZnI3Dg4ElQ6tlv82qLc/UNHtFsgZSKZ7KjsUNAo1BF1SoYDjkGKHJyCrYyWjFecmXpvvG/KJ9A/oe0H12odPLQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-arm64@0.18.14:
resolution: {integrity: sha512-h3OqR80Da4oQCIa37zl8tU5MwHQ7qgPV0oVScPfKJK21fSRZEhLE4IIVpmcOxfAVmqjU6NDxcxhYaM8aDIGRLw==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-x64@0.18.14:
resolution: {integrity: sha512-ha4BX+S6CZG4BoH9tOZTrFIYC1DH13UTCRHzFc3GWX74nz3h/N6MPF3tuR3XlsNjMFUazGgm35MPW5tHkn2lzQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm64@0.18.14:
resolution: {integrity: sha512-IXORRe22In7U65NZCzjwAUc03nn8SDIzWCnfzJ6t/8AvGx5zBkcLfknI+0P+hhuftufJBmIXxdSTbzWc8X/V4w==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm@0.18.14:
resolution: {integrity: sha512-5+7vehI1iqru5WRtJyU2XvTOvTGURw3OZxe3YTdE9muNNIdmKAVmSHpB3Vw2LazJk2ifEdIMt/wTWnVe5V98Kg==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ia32@0.18.14:
resolution: {integrity: sha512-BfHlMa0nibwpjG+VXbOoqJDmFde4UK2gnW351SQ2Zd4t1N3zNdmUEqRkw/srC1Sa1DRBE88Dbwg4JgWCbNz/FQ==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-loong64@0.18.14:
resolution: {integrity: sha512-j2/Ex++DRUWIAaUDprXd3JevzGtZ4/d7VKz+AYDoHZ3HjJzCyYBub9CU1wwIXN+viOP0b4VR3RhGClsvyt/xSw==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-mips64el@0.18.14:
resolution: {integrity: sha512-qn2+nc+ZCrJmiicoAnJXJJkZWt8Nwswgu1crY7N+PBR8ChBHh89XRxj38UU6Dkthl2yCVO9jWuafZ24muzDC/A==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ppc64@0.18.14:
resolution: {integrity: sha512-aGzXzd+djqeEC5IRkDKt3kWzvXoXC6K6GyYKxd+wsFJ2VQYnOWE954qV2tvy5/aaNrmgPTb52cSCHFE+Z7Z0yg==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-riscv64@0.18.14:
resolution: {integrity: sha512-8C6vWbfr0ygbAiMFLS6OPz0BHvApkT2gCboOGV76YrYw+sD/MQJzyITNsjZWDXJwPu9tjrFQOVG7zijRzBCnLw==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-s390x@0.18.14:
resolution: {integrity: sha512-G/Lf9iu8sRMM60OVGOh94ZW2nIStksEcITkXdkD09/T6QFD/o+g0+9WVyR/jajIb3A0LvBJ670tBnGe1GgXMgw==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-x64@0.18.14:
resolution: {integrity: sha512-TBgStYBQaa3EGhgqIDM+ECnkreb0wkcKqL7H6m+XPcGUoU4dO7dqewfbm0mWEQYH3kzFHrzjOFNpSAVzDZRSJw==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/netbsd-x64@0.18.14:
resolution: {integrity: sha512-stvCcjyCQR2lMTroqNhAbvROqRjxPEq0oQ380YdXxA81TaRJEucH/PzJ/qsEtsHgXlWFW6Ryr/X15vxQiyRXVg==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/openbsd-x64@0.18.14:
resolution: {integrity: sha512-apAOJF14CIsN5ht1PA57PboEMsNV70j3FUdxLmA2liZ20gEQnfTG5QU0FhENo5nwbTqCB2O3WDsXAihfODjHYw==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/sunos-x64@0.18.14:
resolution: {integrity: sha512-fYRaaS8mDgZcGybPn2MQbn1ZNZx+UXFSUoS5Hd2oEnlsyUcr/l3c6RnXf1bLDRKKdLRSabTmyCy7VLQ7VhGdOQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-arm64@0.18.14:
resolution: {integrity: sha512-1c44RcxKEJPrVj62XdmYhxXaU/V7auELCmnD+Ri+UCt+AGxTvzxl9uauQhrFso8gj6ZV1DaORV0sT9XSHOAk8Q==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-ia32@0.18.14:
resolution: {integrity: sha512-EXAFttrdAxZkFQmpvcAQ2bywlWUsONp/9c2lcfvPUhu8vXBBenCXpoq9YkUvVP639ld3YGiYx0YUQ6/VQz3Maw==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-x64@0.18.14:
resolution: {integrity: sha512-K0QjGbcskx+gY+qp3v4/940qg8JitpXbdxFhRDA1aYoNaPff88+aEwoq45aqJ+ogpxQxmU0ZTjgnrQD/w8iiUg==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@types/node@16.18.38:
resolution: {integrity: sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ==}
dev: true
/esbuild@0.18.14:
resolution: {integrity: sha512-uNPj5oHPYmj+ZhSQeYQVFZ+hAlJZbAGOmmILWIqrGvPVlNLbyOvU5Bu6Woi8G8nskcx0vwY0iFoMPrzT86Ko+w==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@esbuild/android-arm': 0.18.14
'@esbuild/android-arm64': 0.18.14
'@esbuild/android-x64': 0.18.14
'@esbuild/darwin-arm64': 0.18.14
'@esbuild/darwin-x64': 0.18.14
'@esbuild/freebsd-arm64': 0.18.14
'@esbuild/freebsd-x64': 0.18.14
'@esbuild/linux-arm': 0.18.14
'@esbuild/linux-arm64': 0.18.14
'@esbuild/linux-ia32': 0.18.14
'@esbuild/linux-loong64': 0.18.14
'@esbuild/linux-mips64el': 0.18.14
'@esbuild/linux-ppc64': 0.18.14
'@esbuild/linux-riscv64': 0.18.14
'@esbuild/linux-s390x': 0.18.14
'@esbuild/linux-x64': 0.18.14
'@esbuild/netbsd-x64': 0.18.14
'@esbuild/openbsd-x64': 0.18.14
'@esbuild/sunos-x64': 0.18.14
'@esbuild/win32-arm64': 0.18.14
'@esbuild/win32-ia32': 0.18.14
'@esbuild/win32-x64': 0.18.14
dev: true
/just-split@3.2.0:
resolution: {integrity: sha512-hh57dN5koTBkmg3T6gBFISVVaW5bgZ6Ct1W5KODD5M7hQJKqGzTKkfMwOil8MBxyztLQEjh/v6UGXE8cP5tnqQ==}
dev: false
/prettier@3.0.0:
resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==}
engines: {node: '>=14'}
hasBin: true
dev: true
/tunnel@0.0.6:
resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
dev: false
/typescript@5.1.6:
resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
dev: false

22
src/index.ts Normal file
View File

@ -0,0 +1,22 @@
import { install, isInstalled } from "./stages/install";
import { configure } from "./stages/configure";
import { push } from "./stages/push";
import { getState, saveState, info } from "@actions/core";
const isPost = !!getState("isPost");
const main = async () => {
if (await isInstalled()) {
info("Skipping attic installation because it is already installed");
} else {
await install();
}
await configure();
};
if (!isPost) {
saveState("isPost", true);
main();
} else {
push();
}

31
src/stages/configure.ts Normal file
View File

@ -0,0 +1,31 @@
import * as core from "@actions/core";
import { exec } from "@actions/exec";
import { saveStorePaths } from "../utils";
export const configure = async () => {
core.startGroup("Configure attic");
try {
const endpoint = core.getInput("endpoint");
const cache = core.getInput("cache");
const token = core.getInput("token");
const skipUse = core.getInput("skip-use");
core.info("Logging in to attic cache");
await exec("/run/current-system/sw/bin/attic", ["login", "--set-default", cache, endpoint, token]);
if (skipUse === "true") {
core.info("Not adding attic cache to substituters as skip-use is set to true");
} else {
core.info("Adding attic cache to substituters");
await exec("/run/current-system/sw/bin/attic", ["use", cache]);
}
core.info("Collecting store paths before build");
await saveStorePaths();
} catch (e) {
core.setFailed(`Action failed with error: ${e}`);
}
core.endGroup();
};

40
src/stages/install.ts Normal file
View File

@ -0,0 +1,40 @@
import * as core from "@actions/core";
import { exec } from "@actions/exec";
import { writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
export const install = async () => {
core.startGroup("Install attic");
core.info("Installing attic");
const installScript = await fetch(
"https://raw.githubusercontent.com/zhaofengli/attic/main/.github/install-attic-ci.sh",
).then((r) => {
if (!r.ok) {
core.setFailed(`Action failed with error: ${r.statusText}`);
core.endGroup();
process.exit(1);
}
return r.text();
});
try {
const installScriptPath = join(tmpdir(), "install-attic-ci.sh");
await writeFile(installScriptPath, installScript);
core.info("Running install script");
await exec("bash", [installScriptPath]);
} catch (e) {
core.setFailed(`Action failed with error: ${e}`);
}
core.endGroup();
};
export const isInstalled = async () => {
let return_code = await exec("/run/current-system/sw/bin/attic", ["-V"]);
return return_code === 0;
};

40
src/stages/push.ts Normal file
View File

@ -0,0 +1,40 @@
import * as core from "@actions/core";
import { exec } from "@actions/exec";
import splitArray from "just-split";
import { saveStorePaths, getStorePaths } from "../utils";
export const push = async () => {
core.startGroup("Push to Attic");
try {
const skipPush = core.getInput("skip-push");
if (skipPush === "true") {
core.info("Pushing to cache is disabled by skip-push");
} else {
const cache = core.getInput("cache");
core.info("Pushing to cache");
const oldPaths = await getStorePaths();
await saveStorePaths();
const newPaths = await getStorePaths();
const addedPaths = newPaths
.filter((p) => !oldPaths.includes(p))
.filter(
(p) => !p.endsWith(".drv") && !p.endsWith(".drv.chroot") && !p.endsWith(".check") && !p.endsWith(".lock"),
);
const splitAddedPaths = splitArray(addedPaths, 25);
for (const addedPaths of splitAddedPaths) {
await exec("/run/current-system/sw/bin/attic", ["push", cache, ...addedPaths]);
}
}
} catch (e) {
core.warning(`Action encountered error: ${e}`);
core.info("Not considering errors during push a failure.");
}
core.endGroup();
};

17
src/utils.ts Normal file
View File

@ -0,0 +1,17 @@
import { exec } from "@actions/exec";
import { readFile } from "node:fs/promises";
export const saveStorePaths = async () => {
await exec("sh", ["-c", "nix path-info --all --json > /tmp/store-paths"]);
};
export const getStorePaths = async () => {
const rawStorePaths = JSON.parse(await readFile("/tmp/store-paths", "utf8")) as { path: string }[];
// compatibility with Nix 2.18
if (Array.isArray(rawStorePaths)) {
return rawStorePaths.map((path) => path.path);
};
return Object.keys(rawStorePaths);
};

14
test.nix Normal file
View File

@ -0,0 +1,14 @@
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
pkgs = import (
fetchTarball {
url =
lock.nodes.nixpkgs.locked.url
or "https://github.com/NixOS/nixpkgs/archive/${lock.nodes.nixpkgs.locked.rev}.tar.gz";
sha256 = lock.nodes.nixpkgs.locked.narHash;
}
) {};
in
pkgs.runCommand "non-reproducible-test" {} ''
echo ${toString builtins.currentTime} > $out
''

16
tsconfig.json Normal file
View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"strict": true,
"downlevelIteration": true,
"module": "esnext",
"target": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"isolatedModules": true,
"skipLibCheck": true,
"noEmit": true
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "**/node_modules/*"]
}