Skip to content

Commit

Permalink
feat(nix): add a script to generate ci files
Browse files Browse the repository at this point in the history
  • Loading branch information
deemp committed Apr 29, 2024
1 parent ec227ca commit b28d566
Show file tree
Hide file tree
Showing 3 changed files with 351 additions and 2 deletions.
20 changes: 19 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
pkgs.writeShellApplication {
name = "write";
text = ''
mkdir -p "$(dirname ${path})"
cat > ${path} <<'EOF'
${value}
EOF
Expand Down Expand Up @@ -78,6 +79,23 @@
description = "write action.yml-s and tables for README-s";
};

writeBuildjetCI = writeYAML ".github/workflows/buildjet-ci.yaml" (
import ./nix/ci.nix { backend = "buildjet"; }
);

writeActionsCI = writeYAML ".github/workflows/ci.yaml" (
import ./nix/ci.nix { backend = "actions"; }
);

writeCI = {
text = ''
${lib.getExe config.packages.writeBuildjetCI}
${lib.getExe config.packages.writeActionsCI}
npm run format-ci
'';
description = "write CI files";
};

install = {
runtimeInputs = [ pkgs.nodejs_20 ];
text = ''npm i'';
Expand All @@ -97,7 +115,7 @@
{
prefix = "nix run .#";
packages = {
inherit (config.packages) write install build;
inherit (config.packages) write install build writeCI;
};
}
];
Expand Down
330 changes: 330 additions & 0 deletions nix/ci.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
{ backend }:
let
choose =
optionActions: optionBuildjet: if backend == "actions" then optionActions else optionBuildjet;

backend_ = choose "" ''
# use BuildJet backend
backend: buildjet'';

on = choose ''
push:
# don't run on tags, run on commits
# https://github.com/orgs/community/discussions/25615
tags-ignore:
- "**"
branches:
- "**"
schedule:
- cron: 0 0 * * *'' "";

name = choose "" ''with BuildJet backend'';
in
''
name: Nix CI ${name}
on:
${on}
pull_request:
workflow_dispatch:
env:
# https://stackoverflow.com/a/71158878
git_pull: git pull --rebase origin ''${{ github.head_ref || github.ref_name }}
pin_nixpkgs: nix registry pin nixpkgs github:NixOS/nixpkgs/807c549feabce7eddbf259dbdcec9e0600a0660d
jobs:
# Build the action
# Commit and push the built code
build:
name: Build the action
runs-on: ubuntu-20.04
permissions:
contents: write
actions: write
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: nixbuild/nix-quick-install-action@v27
- name: Restore and save Nix store
uses: ./.
with:
primary-key: build-''${{ runner.os }}-''${{ hashFiles('**/package-lock.json', 'package.json', 'flake.nix', 'flake.lock') }}
paths: |
~/.npm
# do purge caches
purge: true
# purge all versions of the cache
purge-prefixes: build-''${{ runner.os }}-
# created more than 0 seconds ago relative to the start of the `Post Restore` phase
purge-created: 0
# except the version with the `primary-key`, if it exists
purge-primary-key: never
${backend_}
# # Uncomment to debug this job
# - name: Setup tmate session
# uses: mxschmitt/action-tmate@v3
- name: Configure git
env:
# required for gh
GITHUB_TOKEN: ''${{ secrets.GITHUB_TOKEN }}
run: |
''${{ github.head_ref && format('gh pr checkout {0}', github.event.pull_request.number) || ${"''"}}}
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Rebase
run: ''${{ env.git_pull }}
- name: Install packages & Build the action
run: nix run .#install
- name: Update docs
run: nix run .#write
- name: Commit & push changes
run: |
git add dist
git commit -m "chore: build the action" || echo "Nothing to commit"
git add .
git commit -m "chore: update docs" || echo "Nothing to commit"
git push
# Make `individual` caches
# Restore `individual` or `common` caches
# Usually, there should be no `individual` caches to restore as they're purged by `merge-similar-caches`
make-similar-caches:
name: Make similar caches
needs: build
permissions:
actions: write
strategy:
matrix:
os:
- macos-11
- macos-12
- ubuntu-20.04
- ubuntu-22.04
id:
- 1
- 2
runs-on: ''${{ matrix.os }}
steps:
- name: Checkout this repo
uses: actions/checkout@v4
- name: Rebase
run: ''${{ env.git_pull }}
- uses: nixbuild/nix-quick-install-action@v27
- name: Restore and save Nix store - ''${{ matrix.id }}
uses: ./.
with:
# save a new cache every time `ci.yaml` changes
primary-key: similar-cache-''${{ matrix.os }}-individual-''${{ matrix.id }}-''${{ hashFiles('.github/workflows/ci.yaml') }}
# otherwise, restore a common cache if and only if it matches the current `ci.yaml`
restore-prefixes-first-match: similar-cache-''${{ matrix.os }}-common-''${{ hashFiles('.github/workflows/ci.yaml') }}
# do purge caches
purge: true
# purge all versions of the cache
purge-prefixes: similar-cache-''${{ matrix.os }}-individual-''${{ matrix.id }}-
# created more than 0 seconds ago relative to the start of the `Post Restore` phase
purge-created: 0
# except the version with the `primary-key`, if it exists
purge-primary-key: never
${backend_}
- name: Pin nixpkgs
run: ''${{ env.pin_nixpkgs }}
- name: Install nixpkgs#poetry
if: ''${{ matrix.id == 1 }}
run: nix profile install nixpkgs#poetry
- name: Install nixpkgs#nodejs
if: ''${{ matrix.id == 2 }}
run: nix profile install nixpkgs#nodejs
# Merge similar `individual` caches
# Purge `individual` caches and old `common` caches
# Save new `common` caches
merge-similar-caches:
name: Merge similar caches
needs: make-similar-caches
permissions:
actions: write
strategy:
matrix:
os:
- macos-11
- macos-12
- ubuntu-20.04
- ubuntu-22.04
runs-on: ''${{ matrix.os }}
steps:
- name: Checkout this repo
uses: actions/checkout@v4
- name: Rebase
run: ''${{ env.git_pull }}
- uses: nixbuild/nix-quick-install-action@v27
- name: Restore and save Nix store
uses: ./.
with:
primary-key: similar-cache-''${{ matrix.os }}-common-''${{ hashFiles('.github/workflows/ci.yaml') }}
# when there's a common cache hit, don't restore individual caches
skip-restore-on-hit-primary-key: true
# otherwise, restore individual caches, but not their old versions
restore-prefixes-all-matches: |
similar-cache-''${{ matrix.os }}-individual-1-''${{ hashFiles('.github/workflows/ci.yaml') }}
similar-cache-''${{ matrix.os }}-individual-2-''${{ hashFiles('.github/workflows/ci.yaml') }}
# do purge caches
purge: true
# purge all versions of the cache
purge-prefixes: similar-cache-''${{ matrix.os }}-common-
# created more than 0 seconds ago relative to the start of the `Post Restore` phase
purge-created: 0
# except the version with the `primary-key`, if it exists
purge-primary-key: never
${backend_}
- name: Pin nixpkgs
run: ''${{ env.pin_nixpkgs }}
# Stuff in a profile can survive garbage collection.
# Therefore, profiles are ignored when restoring a cache.
# So, the current profile should be the default profile created by nix-quick-install-action.
# The default profile should contain only nix.
- name: List profile (should be empty)
run: nix profile list
- name: Check that the profile is empty
shell: bash
run: |
nix profile list \
| grep 'Index' \
| wc -l \
| xargs test 1 -eq
- name: Install nixpkgs#poetry
run: nix profile install nixpkgs#poetry
- name: Install nixpkgs#nodejs
run: nix profile install nixpkgs#nodejs
- name: Run poetry
run: poetry --version
- name: Run node
run: node --version
compare-run-times:
name: Job with caching
needs: merge-similar-caches
permissions:
actions: write
strategy:
matrix:
do-cache:
- true
- false
os:
- macos-11
- macos-12
- ubuntu-20.04
- ubuntu-22.04
runs-on: ''${{ matrix.os }}
steps:
- name: Checkout this repo
uses: actions/checkout@v4
- name: Rebase
run: ''${{ env.git_pull }}
- uses: nixbuild/nix-quick-install-action@v27
- name: Restore and save Nix store
if: ''${{ matrix.do-cache }}
uses: ./.
with:
# save a new cache every time ci file changes
primary-key: cache-''${{ matrix.os }}-''${{ hashFiles('.github/workflows/ci.yaml') }}
restore-prefixes-first-match: cache-''${{ matrix.os }}-
# do purge caches
purge: true
# purge all versions of the cache
purge-prefixes: cache-''${{ matrix.os }}-
# created more than 0 seconds ago relative to the start of the `Post Restore` phase
purge-created: 0
# except the version with the `primary-key`, if it exists
purge-primary-key: never
# and collect garbage in the Nix store until it reaches this size in bytes
gc-max-store-size: 8000000000
${backend_}
# Uncomment to debug this job
# - name: Setup tmate session
# uses: mxschmitt/action-tmate@v3
- name: Show profile
run: nix profile list
- name: Pin nixpkgs
run: ''${{ env.pin_nixpkgs }}
- name: List registry
run: nix registry list
- name: Install nixpkgs
run: nix profile install $(nix flake archive nixpkgs --json | jq -r '.path')
- name: Show profile
run: nix profile list
- name: Install nixpkgs#hello
run: |
nix profile install nixpkgs#hello
- name: Install nixpkgs#cachix
run: |
nix profile install nixpkgs#cachix
- name: Install nixpkgs#nixpkgs-fmt
run: |
nix profile install nixpkgs#nixpkgs-fmt
- name: Install nixpkgs#alejandra
run: |
nix profile install nixpkgs#alejandra
- name: Install nixpkgs#nixd
run: |
nix profile install nixpkgs#nixd
- name: Install nixpkgs#ghc
run: |
nix profile install nixpkgs#ghc
- name: Install nixpkgs#haskell-language-server
run: |
nix profile install nixpkgs#haskell-language-server
- name: Install nixpkgs#purescript
run: |
nix profile install nixpkgs#purescript
- name: Install nixpkgs#nodejs
run: |
nix profile install nixpkgs#nodejs
- name: Show profile
run: nix profile list
''
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"build": "MERGE=\"$(cat src/templates/merge.sql)\"; printf 'export const mergeSqlTemplate = `\n%s\n`' \"$MERGE\" > src/templates/merge.ts; tsc && ncc build -o dist/restore src/restore.ts && ncc build -o dist/save src/save.ts && ncc build -o dist/restore-only src/restoreOnly.ts && ncc build -o dist/save-only src/saveOnly.ts",
"test": "tsc --noEmit && jest --coverage",
"lint": "eslint **/*.ts --cache",
"format": "prettier --write **/*.ts .github/workflows/ci.yaml **/*.md",
"format": "prettier --write **/*.ts **/*.md **/action.yml",
"format-ci": "prettier --write .github/workflows/*.yaml",
"format-check": "prettier --check **/*.ts",
"readme": "npx action-docs -u; (cd save; npx action-docs -u); (cd restore; npx action-docs -u); prettier --write restore/README.md save/README.md README.md"
},
Expand Down

0 comments on commit b28d566

Please sign in to comment.