Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Nix build action #336

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/spotty-tools-camp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nix-build": minor
---

add nix-build github action
5 changes: 5 additions & 0 deletions .changeset/wet-lamps-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"setup-nix": patch
---

Only enable Cachix when specified by the inputs.
1 change: 1 addition & 0 deletions actions/nix-build/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# nix-build
3 changes: 3 additions & 0 deletions actions/nix-build/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# nix-build

> Builds a nix project and uploads its build artifacts to a cache
129 changes: 129 additions & 0 deletions actions/nix-build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: nix-build
description: "Builds all manifest models and uploads them to a specified cache"

inputs:
# general inputs --------------------------------
add-packages:
description: "Additional packages to build on top of the declared check packages (space separated) - not used if setup-only=true"
required: false
default: ""

# cache inputs ----------------------------------
cache-url:
description: "Nix cache URL"
required: false
default: ""
cache-privkey:
description: "Nix cache binary private signing key - not used if setup-only=true"
required: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we enforce signing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose to enforce we could add a check where if setup-only != true and this is empty, to fail?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory you can use this action without any cache setup - it will still build your flake and all derivations. It will just be slower.

default: ""

# aws inputs --------------------------
# see https://github.com/aws-actions/configure-aws-credentials/blob/main/action.yml
aws-region:
description: "AWS region"
required: true
role-to-assume:
description: The Amazon Resource Name (ARN) of the role to assume. Use the provided credentials to assume an IAM role and configure the Actions environment with the assumed role credentials rather than with the provided credentials.
required: false
role-duration-seconds:
description: Role duration in seconds. Default is one hour.
required: false

# grafana inputs --------------------------
metrics-enabled:
description: "enables grafana metrics"
required: false
default: true
metrics-job-name:
description: "grafana metrics job name"
required: false
default: nix-build
gc-host:
description: "grafana hostname"
required: false
gc-basic-auth:
description: "grafana basic auth"
required: false
gc-org-id:
description: "grafana org/tenant id"
required: false

runs:
using: composite
steps:
- name: AWS credentials
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
aws-region: ${{ inputs.aws-region }}
role-to-assume: ${{ inputs.role-to-assume }}
role-duration-seconds: ${{ inputs.role-duration-seconds }}
- name: Run check package builds
shell: bash
run: |
# run check package builds
nix flake check --impure --all-systems
- name: Build additional packages to cache
if: inputs.add-packages != '' # only run if there are packages specified
shell: bash
run: |
# builds packages specified in `add-packages` since they may not exist in checks
PKGS=()
for key in ${{ inputs.add-packages }}; do
PKGS+=(".#\"$key\"") # build model name with path - example: .#mf
done
nix build --no-link --print-out-paths --verbose --narinfo-cache-negative-ttl 0 ${PKGS[*]}
- name: Get models from flake check
shell: bash
id: getModels
run: |
# get models from the flake check
PKGS=$(nix flake show --json --impure --all-systems . | jq -r '[.packages | .[] | keys] | flatten | unique | join(" ")')
PKGS+=" ${{ inputs.add-packages }}" # append packages specified by inputs
echo "pkgs=$PKGS" >> $GITHUB_OUTPUT
- name: Calculate output + derivation paths
shell: bash
id: buildPaths
run: |
# calculate output + derivation paths
PKGS=()
for key in ${{ steps.getModels.outputs.pkgs }}; do
PKGS+=(".#\"$key\"") # build model name with path - example: .#mf
done

# get runtime output
PATHS="$(nix derivation show --impure ${PKGS[*]} | jq -r '.[] | .outputs | .[] | .path' | tr '\n' ' ')"

# # experimental get build time derivation
# # get build time derivation - does not copy additional build-time dependencies
# # assumption that other build-time dependencies are available through other nix caches
# PATHS+=" $(nix derivation show --impure ${PKGS[*]} | jq -r 'keys[]' | tr '\n' ' ')"

# build all derivations, so we can sign their build artifacts
nix build --impure ${PKGS[*]}

echo "paths=$PATHS" >> $GITHUB_OUTPUT
- name: Sign all paths locally
if: inputs.cache-privkey != ''
shell: bash
run: |
# sign paths
echo "${{ inputs.cache-privkey }}" > priv.pem
nix store sign -k priv.pem --verbose ${{ steps.buildPaths.outputs.paths }}
- name: Copy all paths to bucket
if: inputs.cache-url != ''
shell: bash
run: |
# push to bucket
nix copy --verbose --narinfo-cache-positive-ttl 0 --to ${{ inputs.cache-url }} ${{ steps.buildPaths.outputs.paths }}

- name: Collect metrics
if: inputs.metrics-enabled
id: collect-gha-metrics
uses: smartcontractkit/push-gha-metrics-action@e34ae8a4df60f4d9fdef1e32a69747bab130840e # v2.2.0
with:
basic-auth: ${{ inputs.gc-basic-auth }}
hostname: ${{ inputs.gc-host }}
org-id: ${{ inputs.gc-org-id }}
this-job-name: ${{ inputs.metrics-job-name }}
continue-on-error: true
11 changes: 11 additions & 0 deletions actions/nix-build/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "nix-build",
"version": "0.0.0",
"description": "Builds a nix project and uploads its build artifacts to a cache",
"private": true,
"scripts": {},
"author": "@smartcontractkit",
"license": "MIT",
"dependencies": {},
"repository": "https://github.com/smartcontractkit/.github"
}
7 changes: 7 additions & 0 deletions actions/nix-build/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "nix-build",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "actions/nix-build",
"targets": {}
}
1 change: 1 addition & 0 deletions actions/setup-nix/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ runs:
sudo ln -s ~/.aws $ROOT_PATH

- uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26
if: inputs.enable-cachix == 'true'
ro-tex marked this conversation as resolved.
Show resolved Hide resolved
with:
install_url: https://releases.nixos.org/nix/nix-2.18.1/install
nix_path: nixpkgs=channel:nixos-unstable
Expand Down