commit abb495c57addb4c25b57f09bc184ddfb64699fde Author: Jalil David Salamé Messina Date: Sun Dec 15 20:32:18 2024 +0100 feat: create action Hopefully it works? diff --git a/README.md b/README.md new file mode 100644 index 0000000..b2ba720 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Nix Flake outputs size + +Use `nix path-info` to query the size of flake outputs and produce a markdown report. + +You can post this report as a comment to the PR associated with the current branch and/or export the report as a markdown artifact. + +Requires `nix`, `jq`, `curl`, `sed` and `coreutils` to be in path. + +## Usage + +```yaml +- name: Generate size report + uses: https://git.salame.cl/jalil/nix-flake-outputs-size@main + with: # Default values + comment-on-pr: 'true' + generate-artifact: 'false' + artifact-name: 'size-report.md' +``` + +For more details see the [action.yaml](./action.yml) file. diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..b28ba69 --- /dev/null +++ b/action.yml @@ -0,0 +1,80 @@ +name: 'Nix Flake Outputs Size Report' +author: Jalil David Salamé Messina +description: | + Use `nix path-info` to query the size of flake outputs and produce a markdown + report. + + You can post this report as a comment to the PR associated with the current + branch and/or export the report as a markdown artifact. + + Requires `nix`, `jq`, `curl`, `sed` and `coreutils` to be in path. + + Usage: + + ```yaml + - name: Generate size report + uses: https://git.salame.cl/jalil/nix-flake-outputs-size@main + with: # Default values + comment-on-pr: 'true' + generate-artifact: 'false' + artifact-name: 'size-report.md' + ``` +inputs: + comment-on-pr: + description: Comment the report on the PR associated with the current branch. + default: 'true' + generate-artifact: + description: Export the generated markdown document as an artifact. + default: 'false' + artifact-name: + description: The name of the generated artifact. + default: 'size-report.md' +outputs: +runs: + using: 'composite' + steps: + - name: Create report + run: create-report.sh + - name: Upload Artifact + uses: https://code.forgejo.org/forgejo/upload-artifact@v4 + if: input.generate-artifact + with: + path: size-report.md + name: input.artifact-name + - name: Upload Report + if: input.comment-on-pr + run: | + set -eu + + # For push & tag events it'll bet GITHUB_REF_NAME, for pull_request events it'll be GITHUB_HEAD_REF + head_ref=${GITHUB_REF_NAME-$GITHUB_HEAD_REF} + + pr_number=$(curl -X 'GET' \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/pulls?state=open&sort=recentupdate" \ + -H 'accept: application/json' | + jq --arg head_ref "$head_ref" '.[] | select(.head.ref == $head_ref) | .number') + + # Protect against running before a PR is made or if it is triggered on the main branch + if [ -z "$pr_number" ]; then + echo "No PR created for this commit" + exit 0 + fi + + echo "Retrieved index: $pr_number" >&2 + echo "Expected PR URL: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pulls/$pr_number" >&2 + + echo 'Generating comment body' >&2 + comment=$(cat size-report.md) + + echo 'Posting comment:' >&2 + echo "$comment" >&2 + + echo 'Request data:' >&2 + data=$(echo '{}' | jq --arg comment "$comment" '.body=$comment') + echo "$data" >&2 + curl -o - -X 'POST' \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/issues/$pr_number/comments" \ + -H 'accept: application/json' \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H 'Content-Type: application/json' \ + -d "$data" diff --git a/create-report.sh b/create-report.sh new file mode 100755 index 0000000..0b01a50 --- /dev/null +++ b/create-report.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +set -eu + +echo 'Retrieving Flake information' >&2 +flake_info=$(nix flake show --json 2>/dev/null) +packages=$( + jq --raw-output '.packages."x86_64-linux" | keys[]' <<-EOF + $flake_info + EOF +) +echo "Packages:" >&2 +echo "$packages" >&2 +configurations=$( + jq --raw-output '.nixosConfigurations | keys[]' <<-EOF + $flake_info + EOF +) +echo "NixOS Configurations:" >&2 +echo "$configurations" >&2 + +package_size_table() { + table='| Installable | NAR Size | Closure Size | +|-------------|---------:|-------------:| +' + for package in $packages; do + echo "Building $package" >&2 + path=$(nix build --print-out-paths ".#$package" 2>/dev/null) + echo "Calculating size of $package" >&2 + row=$(nix path-info --size --closure-size --human-readable "$path" 2>/dev/null | + sed "s/^\(\S\+\)\(\s\+\)\(\S\+\)\(\s\+\)\(\S\+\)$/| \`$package\` | \3 | \5 |/") + table="$table$row +" + done + + printf '%s' "$table" +} + +configuration_size_table() { + table='| NixOS Configuration | NAR Size | Closure Size | +|-------------|---------:|-------------:| +' + for config in $configurations; do + echo "Building $config" >&2 + path=$(nix build --print-out-paths ".#nixosConfigurations.$config.config.system.build.toplevel" 2>/dev/null) + echo "Calculating size of $config" >&2 + row=$(nix path-info --size --closure-size --human-readable "$path" 2>/dev/null | + sed "s/^\(\S\+\)\(\s\+\)\(\S\+\)\(\s\+\)\(\S\+\)$/| \`$config\` | \3 | \5 |/") + table="$table$row +" + done + + printf '%s' "$table" +} + +markdown() { + cat <<-EOF + ## Outputs' size + + ### NixOS Configurations sizes + + $(configuration_size_table) + + ### Package sizes + + $(package_size_table) + EOF +} + +markdown > size-report.md