feat: auto push store paths and add CI (#1)

* feat: add flake devShell

* chore: add prettier

* fix: respect cache input during configure

* feat: auto push paths

* feat: add test workflow

* chore: update index.js

* refactors

* pnpm lock

* more refactors

* remove copying

---------

Co-authored-by: Ryan Cao <70191398+ryanccn@users.noreply.github.com>
This commit is contained in:
seth
2023-07-19 01:53:49 +00:00
committed by GitHub
parent 6e24bce2f4
commit 5dc7b671af
17 changed files with 231 additions and 36 deletions

View File

@@ -1,12 +1,9 @@
import { install } from "./stages/install";
import { configure } from "./stages/configure";
import { push } from "./stages/push";
(async () => {
const main = async () => {
await install();
await configure();
await push();
})().catch((e) => {
console.error(e);
process.exit(1);
});
};
main();

7
src/post.ts Normal file
View File

@@ -0,0 +1,7 @@
import { push } from "./stages/push";
const main = async () => {
await push();
};
main();

View File

@@ -1,11 +1,24 @@
import { getInput, startGroup, endGroup } from "@actions/core";
import * as core from "@actions/core";
import { exec } from "@actions/exec";
import { getStorePaths } from "../utils";
export const configure = async () => {
startGroup("Configure attic");
const endpoint = getInput("endpoint");
const token = getInput("token");
core.startGroup("Configure attic");
await exec("attic", ["login", "--set-default", "ci", endpoint, token]);
endGroup();
try {
const endpoint = core.getInput("endpoint");
const cache = core.getInput("cache");
const token = core.getInput("token");
core.info("Logging in to attic cache");
await exec("attic", ["login", "--set-default", cache, endpoint, token]);
core.info("Collecting store paths before build");
const paths = await getStorePaths();
core.saveState("initial-paths", JSON.stringify(paths));
} catch (e) {
core.setFailed(`Action failed with error: ${e}`);
}
core.endGroup();
};

View File

@@ -1,4 +1,4 @@
import { startGroup, endGroup } from "@actions/core";
import * as core from "@actions/core";
import { exec } from "@actions/exec";
import { fetch } from "ofetch";
@@ -7,23 +7,31 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
export const install = async () => {
startGroup("Install attic");
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)
throw new Error(
`Failed to fetch install script: ${r.status} ${r.statusText}`
);
if (!r.ok) {
core.setFailed(`Action failed with error: ${r.statusText}`);
core.endGroup();
process.exit(1);
}
return r.text();
});
const installScriptPath = join(tmpdir(), "install-attic-ci.sh");
try {
const installScriptPath = join(tmpdir(), "install-attic-ci.sh");
await writeFile(installScriptPath, installScript);
await exec("bash", [installScriptPath]);
await writeFile(installScriptPath, installScript);
core.info("Running install script");
await exec("bash", [installScriptPath]);
} catch (e) {
core.setFailed(`Action failed with error: ${e}`);
}
endGroup();
core.endGroup();
};

View File

@@ -1,9 +1,27 @@
import { getInput, getMultilineInput } from "@actions/core";
import * as core from "@actions/core";
import { exec } from "@actions/exec";
import { getStorePaths } from "../utils";
export const push = async () => {
const cache = getInput("cache");
const paths = getMultilineInput("paths");
core.startGroup("Push to Attic");
await exec("attic", ["push", cache, ...paths]);
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 = JSON.parse(core.getState("initial-paths")) as string[];
const newPaths = await getStorePaths();
const addedPaths = newPaths.filter((p) => !oldPaths.includes(p));
await exec("attic", ["push", cache, ...addedPaths]);
}
} catch (e) {
core.setFailed(`Action failed with error: ${e}`);
}
core.endGroup();
};

21
src/utils.ts Normal file
View File

@@ -0,0 +1,21 @@
import { exec } from "@actions/exec";
import { Writable } from "node:stream";
const streamToString = (stream: Writable): Promise<string> => {
const chunks: Buffer[] = [];
return new Promise((resolve, reject) => {
stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
stream.on("error", (err) => reject(err));
stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
});
};
export const getStorePaths = async () => {
const outStream = new Writable();
await exec("nix", ["path-info", "--all"], { outStream });
const paths = await streamToString(outStream)
.then((res) => res.split("\n"))
.then((paths) => paths.filter(Boolean));
return paths;
};