ci: automatically determine lix-installer url #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Checks | ||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| ref_head: | ||
| default: ${{ github.ref }} | ||
| required: false | ||
| type: string | ||
| impure: | ||
| default: false | ||
| required: false | ||
| type: boolean | ||
| nix_installer: | ||
| default: 'https://install.lix.systems/lix/lix-installer-${{ fromJSON('{"X64":"x86_64","X86":"i686","ARM64":"aarch64","ARM":"armv7l"}')[runner.arch] }}-${{ fromJSON('{"Linux":"linux","macOS":"darwin","Windows":"windows"}')[runner.os] }}' | ||
| required: false | ||
| type: string | ||
| cachix_cache_name: | ||
| default: 'foosteros' | ||
| required: false | ||
| type: string | ||
| cachix_extra_cache_names: | ||
| default: 'cosmic' | ||
| required: false | ||
| type: string | ||
| secrets: | ||
| cachix_auth_token: | ||
| description: 'Token for uploading artifacts to Cachix' | ||
| required: false | ||
| jobs: | ||
| evaluate: | ||
| name: Evaluate Flake | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: DeterminateSystems/nix-installer-action@v16 | ||
| with: | ||
| diagnostic-endpoint: '' | ||
| source-url: ${{ inputs.nix_installer }} | ||
| # TODO: remove when <https://git.lix.systems/lix-project/lix/issues/662> is fixed | ||
| extra-conf: | | ||
| http2 = false | ||
| - uses: cachix/cachix-action@v15 | ||
| with: | ||
| name: ${{ inputs.cachix_cache_name }} | ||
| extraPullNames: ${{ inputs.cachix_extra_cache_names }} | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ inputs.ref_head }} | ||
| # TODO: fix OOMs from using `--all-systems` (maybe just detect what systems have outputs and run commands in sequence like this automatically?) | ||
| - name: 'Pre-evaluate all derivation-type outputs' | ||
| if: inputs.impure != 'true' | ||
| run: | | ||
| outputs="$(for system in x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin; do nix -L flake show --legacy --system "$system" --json | jq --compact-output -r '. as $outputs | paths | select(.[-1] == "type") | . as $path | $outputs | getpath($path) as $type | if ($type == "derivation") then ($path[:-1] | join(".")) elif ($type == "nixos-configuration") then ($path[:-1] + ["config", "system", "build", "toplevel"] | join(".")) else empty end'; done | jq --raw-input --slurp --compact-output -r 'split("\n") | map(select(. != ""))')" | ||
| jq --null-input --raw-input --compact-output --argjson outputs "$outputs" -r '$outputs[]' | xargs -I'{}' nix -L eval --json '.#{}.drvPath' | jq -r | ||
| - if: inputs.impure != 'true' | ||
| run: nix -L --show-trace flake check --no-build --system x86_64-linux | ||
| - if: inputs.impure != 'true' | ||
| run: nix -L --show-trace flake check --no-build --system aarch64-linux | ||
| - if: inputs.impure != 'true' | ||
| run: nix -L --show-trace flake check --no-build --system x86_64-darwin | ||
| - if: inputs.impure != 'true' | ||
| run: nix -L --show-trace flake check --no-build --system aarch64-darwin | ||
| populate: | ||
| name: Populate Checks Matrix | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| checks: ${{ steps.identify.outputs.checks }} | ||
| dependencies: ${{ steps.identify.outputs.dependencies }} | ||
| steps: | ||
| - uses: DeterminateSystems/nix-installer-action@v16 | ||
| with: | ||
| diagnostic-endpoint: '' | ||
| source-url: ${{ inputs.nix_installer }} | ||
| # TODO: remove when <https://git.lix.systems/lix-project/lix/issues/662> is fixed | ||
| extra-conf: | | ||
| http2 = false | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ inputs.ref_head }} | ||
| - id: identify | ||
| name: Identify all system-compatible checks | ||
| env: | ||
| IMPURE: ${{ inputs.impure }} | ||
| run: | | ||
| if ! [ "$IMPURE" = true ]; then | ||
| checks="$(nix -L eval ".#checks.$(nix show-config --json | jq -r .system.value)" --apply 'builtins.mapAttrs (_: drv: drv.drvPath)' --json)" | ||
| else | ||
| checks="$(nix-instantiate --eval --strict --read-write-mode --expr 'builtins.mapAttrs (_: drv: drv.drvPath) (import ./test.nix {})' --json)" | ||
| fi | ||
| echo "checks=$(jq --null-input --raw-input --compact-output --argjson checks "$checks" '$checks | keys')" >> $GITHUB_OUTPUT | ||
| echo "dependencies=$(jq --null-input --raw-input --compact-output --argjson checks "$checks" -r '$checks[]' | xargs -I'{}' sh -c 'if ! [ "$IMPURE" = true ]; then nix path-info --derivation -r '"'{}'"'"^*"; else nix-store --query --requisites'"'{}'"'"^*"; fi | jq --raw-input --slurp '"'"'split("\n") | map(select(. != "")) as $drvs | {"path": $drvs[-1], "references": $drvs[:-1]}'"'" | jq --compact-output --argjson checks "$checks" --slurp 'map({"name": (.path as $drv | $checks | with_entries(select(.value == $drv)) | keys | first | select(. != null)), "value": (.references | map(. as $drv | $checks | with_entries(select(.value == $drv)) | keys | first | select(. != null)))}) | from_entries')" >> $GITHUB_OUTPUT | ||
| check: | ||
| name: 'Check: ${{ matrix.check }}' | ||
| runs-on: ubuntu-latest | ||
| needs: [populate] | ||
| strategy: | ||
| matrix: | ||
| check: ${{ fromJSON(needs.populate.outputs.checks) }} | ||
| outputs: | ||
| cached: ${{ steps.query.outputs.cached }} | ||
| steps: | ||
| - name: Free up runner space | ||
| run: | | ||
| # large docker images | ||
| sudo docker image prune --all --force | ||
| # large packages | ||
| sudo apt-get purge -y '^llvm-.*' 'php.*' '^mongodb-.*' '^mysql-.*' azure-cli google-cloud-cli google-chrome-stable firefox powershell microsoft-edge-stable | ||
| sudo apt-get autoremove -y | ||
| sudo apt-get clean | ||
| # large folders | ||
| sudo rm -rf /var/lib/apt/lists/* /opt/hostedtoolcache /usr/local/games /usr/local/sqlpackage /usr/local/.ghcup /usr/local/share/powershell /usr/local/share/edge_driver /usr/local/share/gecko_driver /usr/local/share/chromium /usr/local/share/chromedriver-linux64 /usr/local/share/vcpkg /usr/local/lib/python* /usr/local/lib/node_modules /usr/local/julia* /opt/mssql-tools /etc/skel /usr/share/vim /usr/share/postgresql /usr/share/man /usr/share/apache-maven-* /usr/share/R /usr/share/alsa /usr/share/miniconda /usr/share/grub /usr/share/gradle-* /usr/share/locale /usr/share/texinfo /usr/share/kotlinc /usr/share/swift /usr/share/doc /usr/share/az_9.3.0 /usr/share/sbt /usr/share/ri /usr/share/icons /usr/share/java /usr/share/fonts /usr/lib/google-cloud-sdk /usr/lib/jvm /usr/lib/mono /usr/lib/R /usr/lib/postgresql /usr/lib/heroku /usr/lib/gcc | ||
| - uses: DeterminateSystems/nix-installer-action@v16 | ||
| with: | ||
| diagnostic-endpoint: '' | ||
| source-url: ${{ inputs.nix_installer }} | ||
| # TODO: remove when <https://git.lix.systems/lix-project/lix/issues/662> is fixed | ||
| extra-conf: | | ||
| http2 = false | ||
| - name: 'Remove AppArmor restrictions on unprivileged user namespaces' | ||
| run: | | ||
| sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 | ||
| - uses: cachix/cachix-action@v15 | ||
| with: | ||
| name: ${{ inputs.cachix_cache_name }} | ||
| extraPullNames: ${{ inputs.cachix_extra_cache_names }} | ||
| authToken: ${{ secrets.cachix_auth_token }} | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ inputs.ref_head }} | ||
| - id: query | ||
| name: 'Check cache for checks.${{ matrix.check }}' | ||
| env: | ||
| IMPURE: ${{ inputs.impure }} | ||
| CHECK: ${{ matrix.check }} | ||
| run: | | ||
| if ! [ "$IMPURE" = true ]; then | ||
| narhash="$(nix -L --show-trace eval --raw ".#checks.$(nix show-config --json | jq -r .system.value).$CHECK" --apply 'builtins.substring 11 32')" | ||
| else | ||
| narhash="$(nix-instantiate --show-trace --eval --expr '{ attr }: (import ./test.nix {}).${attr}.outPath' --argstr attr "$CHECK" --json | jq -r '.[11:43]')" | ||
| fi | ||
| for cache in {${{ inputs.cachix_cache_name }},${{ inputs.cachix_extra_cache_names }}}.cachix.org cache.nixos.org; do | ||
| if curl -sfo /dev/null "https://$cache/$narhash.narinfo"; then | ||
| echo "Found $narhash in $cache" | ||
| echo 'cached=true' >> $GITHUB_OUTPUT | ||
| fi | ||
| done | ||
| - name: 'Waiting for dependencies to be built' | ||
| if: steps.query.outputs.cached != 'true' | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| DEPENDENCIES: ${{ needs.populate.outputs.dependencies }} | ||
| run: | | ||
| for job in $(jq --null-input --raw-input --compact-output --argjson dependencies "$DEPENDENCIES" -r '$dependencies."${{ matrix.check }}"[]'); do | ||
| while (echo -n 'Authorization: Bearer ' && printenv GITHUB_TOKEN) | curl -H @/dev/stdin -sf '${{ github.api_url }}/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs' | jq --arg job "$job" -e '(.jobs[] | select(.name | endswith("Check: " + $job))).status != "completed"' >/dev/null; do | ||
| echo "Waiting on checks.$job..." | ||
| sleep 10 | ||
| done | ||
| done | ||
| - name: 'Build checks.${{ matrix.check }}' | ||
| if: steps.query.outputs.cached != 'true' | ||
| env: | ||
| IMPURE: ${{ inputs.impure }} | ||
| CHECK: ${{ matrix.check }} | ||
| run: | | ||
| if ! [ "$IMPURE" = true ]; then | ||
| nix -L --show-trace build ".#checks.$(nix show-config --json | jq -r .system.value).$CHECK" | ||
| else | ||
| nix-build --show-trace test.nix -A "$CHECK" | ||
| fi | ||