mirror of
https://github.com/DeterminateSystems/nix-installer-action.git
synced 2024-12-23 05:22:21 +01:00
Post run diagnostics (#39)
This commit is contained in:
parent
3ebd1aebb4
commit
d654f7b93a
9 changed files with 7238 additions and 20 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
use flake
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -96,4 +96,6 @@ Thumbs.db
|
||||||
|
|
||||||
# Ignore built ts files
|
# Ignore built ts files
|
||||||
__tests__/runner/*
|
__tests__/runner/*
|
||||||
lib/**/*
|
lib/**/*
|
||||||
|
|
||||||
|
.direnv
|
||||||
|
|
|
@ -104,3 +104,4 @@ inputs:
|
||||||
runs:
|
runs:
|
||||||
using: "node16"
|
using: "node16"
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
post: 'dist/index.js'
|
7063
dist/index.js
vendored
7063
dist/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/licenses.txt
vendored
2
dist/licenses.txt
vendored
|
@ -2,7 +2,7 @@ node-fetch
|
||||||
MIT
|
MIT
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016 - 2020 Node Fetch Team
|
Copyright (c) 2016 David Frank
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
38
flake.lock
Normal file
38
flake.lock
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-schemas": {
|
||||||
|
"locked": {
|
||||||
|
"narHash": "sha256-ifw8Td8kD08J8DxFbYjeIx5naHcDLz7s2IFP3X42I/U=",
|
||||||
|
"rev": "c702cbb663d6d70bbb716584a2ee3aeb35017279",
|
||||||
|
"revCount": 21,
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/flake-schemas/0.1.1/018a4c59-80e1-708a-bb4d-854930c20f72/source.tar.gz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://flakehub.com/f/DeterminateSystems/flake-schemas/%2A.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"narHash": "sha256-g7nIUV4uq1TOVeVIDEZLb005suTWCUjSY0zYOlSBsyE=",
|
||||||
|
"rev": "32dcb45f66c0487e92db8303a798ebc548cadedc",
|
||||||
|
"revCount": 491340,
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2305.491340%2Brev-32dcb45f66c0487e92db8303a798ebc548cadedc/018aebfc-faf0-743e-aeb4-28acf5a64d95/source.tar.gz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://flakehub.com/f/NixOS/nixpkgs/%2A.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-schemas": "flake-schemas",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
29
flake.nix
Normal file
29
flake.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# This flake was initially generated by fh, the CLI for FlakeHub (version 0.1.5)
|
||||||
|
{
|
||||||
|
description = "Development environment for the Nix Installer action for GitHub.";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
flake-schemas.url = "https://flakehub.com/f/DeterminateSystems/flake-schemas/*.tar.gz";
|
||||||
|
nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/*.tar.gz";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, flake-schemas, nixpkgs }:
|
||||||
|
let
|
||||||
|
supportedSystems = [ "x86_64-linux" "aarch64-darwin" ];
|
||||||
|
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
|
||||||
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
});
|
||||||
|
in
|
||||||
|
{
|
||||||
|
schemas = flake-schemas.schemas;
|
||||||
|
|
||||||
|
devShells = forEachSupportedSystem ({ pkgs }: {
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
nodejs-18_x
|
||||||
|
nixpkgs-fmt
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
118
src/main.ts
118
src/main.ts
|
@ -1,6 +1,8 @@
|
||||||
import * as actions_core from "@actions/core";
|
import * as actions_core from "@actions/core";
|
||||||
|
import * as github from "@actions/github";
|
||||||
import { mkdtemp, chmod, access } from "node:fs/promises";
|
import { mkdtemp, chmod, access } from "node:fs/promises";
|
||||||
import { spawn } from "node:child_process";
|
import { spawn } from "node:child_process";
|
||||||
|
import { randomUUID } from "node:crypto";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { pipeline } from "node:stream";
|
import { pipeline } from "node:stream";
|
||||||
|
@ -40,6 +42,12 @@ class NixInstallerAction {
|
||||||
trust_runner_user: boolean | null;
|
trust_runner_user: boolean | null;
|
||||||
nix_installer_url: URL;
|
nix_installer_url: URL;
|
||||||
|
|
||||||
|
// Connects the installation diagnostic report to the post-run diagnostic report.
|
||||||
|
// This is for monitoring the real impact of Nix updates, to avoid breaking large
|
||||||
|
// swaths of users at once with botched Nix releases. For example:
|
||||||
|
// https://github.com/NixOS/nix/issues/9052.
|
||||||
|
correlation: string | undefined;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.platform = get_nix_platform();
|
this.platform = get_nix_platform();
|
||||||
this.nix_package_url = action_input_string_or_null("nix-package-url");
|
this.nix_package_url = action_input_string_or_null("nix-package-url");
|
||||||
|
@ -78,13 +86,18 @@ class NixInstallerAction {
|
||||||
"diagnostic-endpoint",
|
"diagnostic-endpoint",
|
||||||
);
|
);
|
||||||
this.trust_runner_user = action_input_bool("trust-runner-user");
|
this.trust_runner_user = action_input_bool("trust-runner-user");
|
||||||
this.nix_installer_url = resolve_nix_installer_url(this.platform);
|
this.correlation = process.env["STATE_correlation"];
|
||||||
|
this.nix_installer_url = resolve_nix_installer_url(
|
||||||
|
this.platform,
|
||||||
|
this.correlation,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private executionEnvironment(): ExecuteEnvironment {
|
private executionEnvironment(): ExecuteEnvironment {
|
||||||
const execution_env: ExecuteEnvironment = {};
|
const execution_env: ExecuteEnvironment = {};
|
||||||
|
|
||||||
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
|
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
|
||||||
|
execution_env.NIX_INSTALLER_DIAGNOSTIC_ATTRIBUTION = this.correlation;
|
||||||
|
|
||||||
if (this.backtrace !== null) {
|
if (this.backtrace !== null) {
|
||||||
execution_env.RUST_BACKTRACE = this.backtrace;
|
execution_env.RUST_BACKTRACE = this.backtrace;
|
||||||
|
@ -398,6 +411,78 @@ class NixInstallerAction {
|
||||||
return local_path;
|
return local_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async report_overall(): Promise<void> {
|
||||||
|
if (this.diagnostic_endpoint == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fetch(this.diagnostic_endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"post-github-workflow-run-report": true,
|
||||||
|
correlation: this.correlation,
|
||||||
|
conclusion: await this.get_workflow_conclusion(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
actions_core.debug(
|
||||||
|
`Error submitting post-run diagnostics report: ${error}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async get_workflow_conclusion(): Promise<
|
||||||
|
undefined | "success" | "failure" | "cancelled" | "unavailable" | "no-jobs"
|
||||||
|
> {
|
||||||
|
if (this.github_token == null) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const octokit = github.getOctokit(this.github_token);
|
||||||
|
const jobs = await octokit.paginate(
|
||||||
|
octokit.rest.actions.listJobsForWorkflowRun,
|
||||||
|
{
|
||||||
|
owner: github.context.repo.owner,
|
||||||
|
repo: github.context.repo.repo,
|
||||||
|
run_id: github.context.runId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
actions_core.debug(`awaited jobs: ${jobs}`);
|
||||||
|
const job = jobs
|
||||||
|
.filter((candidate) => candidate.name === github.context.job)
|
||||||
|
.at(0);
|
||||||
|
if (job === undefined) {
|
||||||
|
return "no-jobs";
|
||||||
|
}
|
||||||
|
|
||||||
|
const outcomes = (job.steps || []).map((j) => j.conclusion || "unknown");
|
||||||
|
|
||||||
|
// Possible values: success, failure, cancelled, or skipped
|
||||||
|
// from: https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||||
|
|
||||||
|
if (outcomes.includes("failure")) {
|
||||||
|
// Any failures fails the job
|
||||||
|
return "failure";
|
||||||
|
}
|
||||||
|
if (outcomes.includes("cancelled")) {
|
||||||
|
// Any cancellations cancels the job
|
||||||
|
return "cancelled";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume success if no jobs failed or were canceled
|
||||||
|
return "success";
|
||||||
|
} catch (error) {
|
||||||
|
actions_core.debug(`Error determining final disposition: ${error}`);
|
||||||
|
return "unavailable";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExecuteEnvironment = {
|
type ExecuteEnvironment = {
|
||||||
|
@ -413,6 +498,7 @@ type ExecuteEnvironment = {
|
||||||
NIX_INSTALLER_PROXY?: string;
|
NIX_INSTALLER_PROXY?: string;
|
||||||
NIX_INSTALLER_SSL_CERT_FILE?: string;
|
NIX_INSTALLER_SSL_CERT_FILE?: string;
|
||||||
NIX_INSTALLER_DIAGNOSTIC_ENDPOINT?: string;
|
NIX_INSTALLER_DIAGNOSTIC_ENDPOINT?: string;
|
||||||
|
NIX_INSTALLER_DIAGNOSTIC_ATTRIBUTION?: string;
|
||||||
NIX_INSTALLER_ENCRYPT?: string;
|
NIX_INSTALLER_ENCRYPT?: string;
|
||||||
NIX_INSTALLER_CASE_SENSITIVE?: string;
|
NIX_INSTALLER_CASE_SENSITIVE?: string;
|
||||||
NIX_INSTALLER_VOLUME_LABEL?: string;
|
NIX_INSTALLER_VOLUME_LABEL?: string;
|
||||||
|
@ -456,7 +542,10 @@ function get_default_planner(): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolve_nix_installer_url(platform: string): URL {
|
function resolve_nix_installer_url(
|
||||||
|
platform: string,
|
||||||
|
correlation?: string,
|
||||||
|
): URL {
|
||||||
// Only one of these are allowed.
|
// Only one of these are allowed.
|
||||||
const nix_installer_branch = action_input_string_or_null(
|
const nix_installer_branch = action_input_string_or_null(
|
||||||
"nix-installer-branch",
|
"nix-installer-branch",
|
||||||
|
@ -467,36 +556,36 @@ function resolve_nix_installer_url(platform: string): URL {
|
||||||
);
|
);
|
||||||
const nix_installer_tag = action_input_string_or_null("nix-installer-tag");
|
const nix_installer_tag = action_input_string_or_null("nix-installer-tag");
|
||||||
const nix_installer_url = action_input_string_or_null("nix-installer-url");
|
const nix_installer_url = action_input_string_or_null("nix-installer-url");
|
||||||
|
const url_suffix = `ci=github&correlation=${correlation}`;
|
||||||
let resolved_nix_installer_url = null;
|
let resolved_nix_installer_url = null;
|
||||||
let num_set = 0;
|
let num_set = 0;
|
||||||
|
|
||||||
if (nix_installer_branch !== null) {
|
if (nix_installer_branch !== null) {
|
||||||
num_set += 1;
|
num_set += 1;
|
||||||
resolved_nix_installer_url = new URL(
|
resolved_nix_installer_url = new URL(
|
||||||
`https://install.determinate.systems/nix/branch/${nix_installer_branch}/nix-installer-${platform}?ci=github`,
|
`https://install.determinate.systems/nix/branch/${nix_installer_branch}/nix-installer-${platform}?${url_suffix}`,
|
||||||
);
|
);
|
||||||
} else if (nix_installer_pr !== null) {
|
} else if (nix_installer_pr !== null) {
|
||||||
num_set += 1;
|
num_set += 1;
|
||||||
resolved_nix_installer_url = new URL(
|
resolved_nix_installer_url = new URL(
|
||||||
`https://install.determinate.systems/nix/pr/${nix_installer_pr}/nix-installer-${platform}?ci=github`,
|
`https://install.determinate.systems/nix/pr/${nix_installer_pr}/nix-installer-${platform}?${url_suffix}`,
|
||||||
);
|
);
|
||||||
} else if (nix_installer_revision !== null) {
|
} else if (nix_installer_revision !== null) {
|
||||||
num_set += 1;
|
num_set += 1;
|
||||||
resolved_nix_installer_url = new URL(
|
resolved_nix_installer_url = new URL(
|
||||||
`https://install.determinate.systems/nix/rev/${nix_installer_revision}/nix-installer-${platform}?ci=github`,
|
`https://install.determinate.systems/nix/rev/${nix_installer_revision}/nix-installer-${platform}?${url_suffix}`,
|
||||||
);
|
);
|
||||||
} else if (nix_installer_tag !== null) {
|
} else if (nix_installer_tag !== null) {
|
||||||
num_set += 1;
|
num_set += 1;
|
||||||
resolved_nix_installer_url = new URL(
|
resolved_nix_installer_url = new URL(
|
||||||
`https://install.determinate.systems/nix/tag/${nix_installer_tag}/nix-installer-${platform}?ci=github`,
|
`https://install.determinate.systems/nix/tag/${nix_installer_tag}/nix-installer-${platform}?${url_suffix}`,
|
||||||
);
|
);
|
||||||
} else if (nix_installer_url !== null) {
|
} else if (nix_installer_url !== null) {
|
||||||
num_set += 1;
|
num_set += 1;
|
||||||
resolved_nix_installer_url = new URL(nix_installer_url);
|
resolved_nix_installer_url = new URL(nix_installer_url);
|
||||||
} else {
|
} else {
|
||||||
resolved_nix_installer_url = new URL(
|
resolved_nix_installer_url = new URL(
|
||||||
`https://install.determinate.systems/nix/nix-installer-${platform}?ci=github`,
|
`https://install.determinate.systems/nix/nix-installer-${platform}?${url_suffix}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,9 +630,20 @@ function action_input_bool(name: string): boolean {
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
if (!process.env["STATE_correlation"]) {
|
||||||
|
const correlation = `GH-${randomUUID()}`;
|
||||||
|
actions_core.saveState("correlation", correlation);
|
||||||
|
process.env["STATE_correlation"] = correlation;
|
||||||
|
}
|
||||||
const installer = new NixInstallerAction();
|
const installer = new NixInstallerAction();
|
||||||
|
|
||||||
await installer.install();
|
const isPost = !!process.env["STATE_isPost"];
|
||||||
|
if (!isPost) {
|
||||||
|
actions_core.saveState("isPost", "true");
|
||||||
|
await installer.install();
|
||||||
|
} else {
|
||||||
|
installer.report_overall();
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) actions_core.setFailed(error);
|
if (error instanceof Error) actions_core.setFailed(error);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue