Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
22c2bb1406 | |||
8e8ff90bd6 | |||
|
5619ef4781 | ||
|
37f74ba5fa | ||
|
6cfb1137df | ||
|
f75ac4b827 | ||
|
6689ac7697 | ||
|
4698511c85 | ||
|
7f0e30fedd | ||
|
40fa276ac0 | ||
|
fae7bd1d97 | ||
|
aa6bedf232 | ||
|
6870271f1d | ||
|
ce977ffab4 | ||
|
8c01d0bda1 | ||
|
88dbb4b600 | ||
|
fd02e7c96c | ||
|
56ba67dfc0 | ||
|
e78c87fc0e | ||
|
7af24dd783 | ||
|
3c5e4de9b2 | ||
|
a2f0acb9d4 | ||
|
ec939ca6ac | ||
|
3b6f7992de |
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
13
.github/workflows/release.yml
vendored
13
.github/workflows/release.yml
vendored
@ -4,20 +4,21 @@ on:
|
|||||||
release:
|
release:
|
||||||
types: [published, edited]
|
types: [published, edited]
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.release.tag_name }}
|
ref: ${{ github.event.release.tag_name }}
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
cache-dependency-path: pnpm-lock.yaml
|
cache-dependency-path: pnpm-lock.yaml
|
||||||
|
10
.github/workflows/test.yml
vendored
10
.github/workflows/test.yml
vendored
@ -16,10 +16,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
cache-dependency-path: pnpm-lock.yaml
|
cache-dependency-path: pnpm-lock.yaml
|
||||||
@ -28,7 +28,7 @@ jobs:
|
|||||||
run: pnpm install && pnpm build
|
run: pnpm install && pnpm build
|
||||||
|
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v22
|
uses: DeterminateSystems/nix-installer-action@v9
|
||||||
|
|
||||||
- name: Setup Attic Cache
|
- name: Setup Attic Cache
|
||||||
uses: ./
|
uses: ./
|
||||||
@ -38,4 +38,4 @@ jobs:
|
|||||||
token: ${{ secrets.ATTIC_TOKEN }}
|
token: ${{ secrets.ATTIC_TOKEN }}
|
||||||
|
|
||||||
- name: Build Nix Package
|
- name: Build Nix Package
|
||||||
run: nix build -f test.nix
|
run: nix-build test.nix
|
||||||
|
@ -1 +1 @@
|
|||||||
16
|
20
|
||||||
|
43
README.md
43
README.md
@ -1,3 +1,44 @@
|
|||||||
# attic-action
|
# attic-action
|
||||||
|
|
||||||
Cache Nix derivations with [attic](https://github.com/zhaofengli/attic).
|
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
|
||||||
|
@ -19,8 +19,11 @@ inputs:
|
|||||||
token:
|
token:
|
||||||
description: "Attic authorization token"
|
description: "Attic authorization token"
|
||||||
required: false
|
required: false
|
||||||
|
skip-use:
|
||||||
|
description: "Set to true to skip using attic cache as a substituter"
|
||||||
|
required: false
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "node16"
|
using: "node20"
|
||||||
main: "dist/index.js"
|
main: "dist/index.js"
|
||||||
post: "dist/index.js"
|
post: "dist/index.js"
|
||||||
|
8
dist/index.js
vendored
Normal file
8
dist/index.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
flake.lock
generated
6
flake.lock
generated
@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1689534811,
|
"lastModified": 1689850295,
|
||||||
"narHash": "sha256-jnSUdzD/414d94plCyNlvTJJtiTogTep6t7ZgIKIHiE=",
|
"narHash": "sha256-fUYf6WdQlhd2H+3aR8jST5dhFH1d0eE22aes8fNIfyk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6cee3b5893090b0f5f0a06b4cf42ca4e60e5d222",
|
"rev": "5df4d78d54f7a34e9ea1f84a22b4fd9baebc68d0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
25
flake.nix
25
flake.nix
@ -1,31 +1,30 @@
|
|||||||
{
|
{
|
||||||
description = "";
|
description = "Github Action for caching Nix derivations with attic";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "nixpkgs/nixos-unstable";
|
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = {nixpkgs, ...}: let
|
outputs = {nixpkgs, ...}: let
|
||||||
mkSystems = sys: builtins.map (arch: "${arch}-${sys}") ["x86_64" "aarch64"];
|
systems = [
|
||||||
systems =
|
"x86_64-linux"
|
||||||
mkSystems "linux"
|
"aarch64-linux"
|
||||||
++ mkSystems "darwin";
|
"x86_64-darwin"
|
||||||
|
"aarch64-darwin"
|
||||||
|
];
|
||||||
|
|
||||||
forAllSystems = nixpkgs.lib.genAttrs systems;
|
forAllSystems = fn: nixpkgs.lib.genAttrs systems (system: fn nixpkgs.legacyPackages.${system});
|
||||||
nixpkgsFor = forAllSystems (system: import nixpkgs {inherit system;});
|
|
||||||
|
|
||||||
forEachSystem = fn:
|
|
||||||
forAllSystems (s: fn nixpkgsFor.${s});
|
|
||||||
in {
|
in {
|
||||||
devShells = forEachSystem (pkgs: {
|
devShells = forAllSystems (pkgs: {
|
||||||
default = pkgs.mkShell {
|
default = pkgs.mkShell {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
actionlint
|
actionlint
|
||||||
nodePackages.pnpm
|
nodejs_20
|
||||||
|
(nodePackages_latest.pnpm.override {nodejs = nodejs_20;})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
formatter = forEachSystem (p: p.nixpkgs-fmt);
|
formatter = forAllSystems (p: p.alejandra);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"ofetch": "^1.1.1"
|
"just-split": "^3.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^16.18.38",
|
"@types/node": "^16.18.38",
|
||||||
@ -19,5 +19,5 @@
|
|||||||
"prettier": "3.0.0",
|
"prettier": "3.0.0",
|
||||||
"typescript": "^5.1.6"
|
"typescript": "^5.1.6"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.6.9"
|
"packageManager": "pnpm@8.7.5"
|
||||||
}
|
}
|
||||||
|
26
pnpm-lock.yaml
generated
26
pnpm-lock.yaml
generated
@ -11,9 +11,9 @@ dependencies:
|
|||||||
'@actions/exec':
|
'@actions/exec':
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
ofetch:
|
just-split:
|
||||||
specifier: ^1.1.1
|
specifier: ^3.2.0
|
||||||
version: 1.1.1
|
version: 3.2.0
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
@ -256,10 +256,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ==}
|
resolution: {integrity: sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/destr@2.0.0:
|
|
||||||
resolution: {integrity: sha512-FJ9RDpf3GicEBvzI3jxc2XhHzbqD8p4ANw/1kPsFBfTvP1b7Gn/Lg1vO7R9J4IVgoMbyUmFrFGZafJ1hPZpvlg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/esbuild@0.18.14:
|
/esbuild@0.18.14:
|
||||||
resolution: {integrity: sha512-uNPj5oHPYmj+ZhSQeYQVFZ+hAlJZbAGOmmILWIqrGvPVlNLbyOvU5Bu6Woi8G8nskcx0vwY0iFoMPrzT86Ko+w==}
|
resolution: {integrity: sha512-uNPj5oHPYmj+ZhSQeYQVFZ+hAlJZbAGOmmILWIqrGvPVlNLbyOvU5Bu6Woi8G8nskcx0vwY0iFoMPrzT86Ko+w==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -290,16 +286,8 @@ packages:
|
|||||||
'@esbuild/win32-x64': 0.18.14
|
'@esbuild/win32-x64': 0.18.14
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/node-fetch-native@1.2.0:
|
/just-split@3.2.0:
|
||||||
resolution: {integrity: sha512-5IAMBTl9p6PaAjYCnMv5FmqIF6GcZnawAVnzaCG0rX2aYZJ4CxEkZNtVPuTRug7fL7wyM5BQYTlAzcyMPi6oTQ==}
|
resolution: {integrity: sha512-hh57dN5koTBkmg3T6gBFISVVaW5bgZ6Ct1W5KODD5M7hQJKqGzTKkfMwOil8MBxyztLQEjh/v6UGXE8cP5tnqQ==}
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ofetch@1.1.1:
|
|
||||||
resolution: {integrity: sha512-SSMoktrp9SNLi20BWfB/BnnKcL0RDigXThD/mZBeQxkIRv1xrd9183MtLdsqRYLYSqW0eTr5t8w8MqjNhvoOQQ==}
|
|
||||||
dependencies:
|
|
||||||
destr: 2.0.0
|
|
||||||
node-fetch-native: 1.2.0
|
|
||||||
ufo: 1.1.2
|
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/prettier@3.0.0:
|
/prettier@3.0.0:
|
||||||
@ -319,10 +307,6 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ufo@1.1.2:
|
|
||||||
resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/uuid@8.3.2:
|
/uuid@8.3.2:
|
||||||
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import { install } from "./stages/install";
|
import { install, isInstalled } from "./stages/install";
|
||||||
import { configure } from "./stages/configure";
|
import { configure } from "./stages/configure";
|
||||||
import { push } from "./stages/push";
|
import { push } from "./stages/push";
|
||||||
import { getState, saveState } from "@actions/core";
|
import { getState, saveState, info } from "@actions/core";
|
||||||
|
|
||||||
const isPost = !!getState("isPost");
|
const isPost = !!getState("isPost");
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
|
if (await isInstalled()) {
|
||||||
|
info("Skipping attic installation because it is already installed");
|
||||||
|
} else {
|
||||||
await install();
|
await install();
|
||||||
|
}
|
||||||
await configure();
|
await configure();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import { exec } from "@actions/exec";
|
import { exec } from "@actions/exec";
|
||||||
import { getStorePaths } from "../utils";
|
import { saveStorePaths } from "../utils";
|
||||||
|
|
||||||
export const configure = async () => {
|
export const configure = async () => {
|
||||||
core.startGroup("Configure attic");
|
core.startGroup("Configure attic");
|
||||||
@ -9,13 +9,20 @@ export const configure = async () => {
|
|||||||
const endpoint = core.getInput("endpoint");
|
const endpoint = core.getInput("endpoint");
|
||||||
const cache = core.getInput("cache");
|
const cache = core.getInput("cache");
|
||||||
const token = core.getInput("token");
|
const token = core.getInput("token");
|
||||||
|
const skipUse = core.getInput("skip-use");
|
||||||
|
|
||||||
core.info("Logging in to attic cache");
|
core.info("Logging in to attic cache");
|
||||||
await exec("attic", ["login", "--set-default", cache, endpoint, token]);
|
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");
|
core.info("Collecting store paths before build");
|
||||||
const paths = await getStorePaths();
|
await saveStorePaths();
|
||||||
core.saveState("initial-paths", JSON.stringify(paths));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.setFailed(`Action failed with error: ${e}`);
|
core.setFailed(`Action failed with error: ${e}`);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import { exec } from "@actions/exec";
|
import { exec } from "@actions/exec";
|
||||||
import { fetch } from "ofetch";
|
|
||||||
|
|
||||||
import { writeFile } from "node:fs/promises";
|
import { writeFile } from "node:fs/promises";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
@ -34,3 +33,8 @@ export const install = async () => {
|
|||||||
|
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isInstalled = async () => {
|
||||||
|
let return_code = await exec("/run/current-system/sw/bin/attic", ["-V"]);
|
||||||
|
return return_code === 0;
|
||||||
|
};
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import { exec } from "@actions/exec";
|
import { exec } from "@actions/exec";
|
||||||
import { getStorePaths } from "../utils";
|
|
||||||
|
import splitArray from "just-split";
|
||||||
|
import { saveStorePaths, getStorePaths } from "../utils";
|
||||||
|
|
||||||
export const push = async () => {
|
export const push = async () => {
|
||||||
core.startGroup("Push to Attic");
|
core.startGroup("Push to Attic");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const skipPush = core.getInput("skip-push");
|
const skipPush = core.getInput("skip-push");
|
||||||
|
|
||||||
if (skipPush === "true") {
|
if (skipPush === "true") {
|
||||||
core.info("Pushing to cache is disabled by skip-push");
|
core.info("Pushing to cache is disabled by skip-push");
|
||||||
} else {
|
} else {
|
||||||
const cache = core.getInput("cache");
|
const cache = core.getInput("cache");
|
||||||
|
|
||||||
core.info("Pushing to cache");
|
core.info("Pushing to cache");
|
||||||
const oldPaths = JSON.parse(core.getState("initial-paths")) as string[];
|
|
||||||
|
const oldPaths = await getStorePaths();
|
||||||
|
await saveStorePaths();
|
||||||
const newPaths = await getStorePaths();
|
const newPaths = await getStorePaths();
|
||||||
const addedPaths = newPaths
|
const addedPaths = newPaths
|
||||||
.filter((p) => !oldPaths.includes(p))
|
.filter((p) => !oldPaths.includes(p))
|
||||||
@ -21,10 +26,14 @@ export const push = async () => {
|
|||||||
(p) => !p.endsWith(".drv") && !p.endsWith(".drv.chroot") && !p.endsWith(".check") && !p.endsWith(".lock"),
|
(p) => !p.endsWith(".drv") && !p.endsWith(".drv.chroot") && !p.endsWith(".check") && !p.endsWith(".lock"),
|
||||||
);
|
);
|
||||||
|
|
||||||
await exec("attic", ["push", cache, ...addedPaths]);
|
const splitAddedPaths = splitArray(addedPaths, 25);
|
||||||
|
for (const addedPaths of splitAddedPaths) {
|
||||||
|
await exec("/run/current-system/sw/bin/attic", ["push", cache, ...addedPaths]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.setFailed(`Action failed with error: ${e}`);
|
core.warning(`Action encountered error: ${e}`);
|
||||||
|
core.info("Not considering errors during push a failure.");
|
||||||
}
|
}
|
||||||
|
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
|
32
src/utils.ts
32
src/utils.ts
@ -1,23 +1,17 @@
|
|||||||
import { exec } from "@actions/exec";
|
import { exec } from "@actions/exec";
|
||||||
import { Writable } from "node:stream";
|
|
||||||
|
|
||||||
class StringStream extends Writable {
|
import { readFile } from "node:fs/promises";
|
||||||
chunks: Buffer[] = [];
|
|
||||||
|
|
||||||
_write(chunk: WithImplicitCoercion<ArrayBuffer | SharedArrayBuffer>, _enc: unknown, next: () => unknown) {
|
export const saveStorePaths = async () => {
|
||||||
this.chunks.push(Buffer.from(chunk));
|
await exec("sh", ["-c", "nix path-info --all --json > /tmp/store-paths"]);
|
||||||
next();
|
};
|
||||||
}
|
export const getStorePaths = async () => {
|
||||||
|
const rawStorePaths = JSON.parse(await readFile("/tmp/store-paths", "utf8")) as { path: string }[];
|
||||||
string() {
|
|
||||||
return Buffer.concat(this.chunks).toString("utf-8");
|
// compatibility with Nix 2.18
|
||||||
}
|
if (Array.isArray(rawStorePaths)) {
|
||||||
}
|
return rawStorePaths.map((path) => path.path);
|
||||||
|
};
|
||||||
export const getStorePaths = async () => {
|
|
||||||
const outStream = new StringStream();
|
return Object.keys(rawStorePaths);
|
||||||
await exec("nix", ["path-info", "--all"], { outStream });
|
|
||||||
const paths = outStream.string().split("\n").filter(Boolean);
|
|
||||||
|
|
||||||
return paths;
|
|
||||||
};
|
};
|
||||||
|
15
test.nix
15
test.nix
@ -1,7 +1,14 @@
|
|||||||
let
|
let
|
||||||
pkgs = import <nixpkgs> { };
|
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
|
||||||
time = with builtins; toString currentTime;
|
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
|
in
|
||||||
pkgs.runCommand "${time}-test" { } ''
|
pkgs.runCommand "non-reproducible-test" {} ''
|
||||||
echo "${time}" > $out
|
echo ${toString builtins.currentTime} > $out
|
||||||
''
|
''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user