nixpkgs-bump.yml

  1name: Nixpkgs Bump PR
  2
  3# Triggers on stable release publish. Opens PR against NixOS/nixpkgs
  4# bumping pkgs/by-name/ma/matcha/package.nix to the new version.
  5# Requires:
  6#   - Fork floatpane/nixpkgs to exist
  7#   - NIXPKGS_BUMP_TOKEN secret: PAT with `repo` scope on floatpane/nixpkgs
  8#     and permission to open PRs against NixOS/nixpkgs
  9#   - Initial matcha package already merged into nixpkgs (this workflow updates, not inits)
 10
 11on:
 12  release:
 13    types: [published]
 14  workflow_dispatch:
 15    inputs:
 16      version:
 17        description: "Version to bump to (without v prefix)"
 18        required: true
 19
 20permissions:
 21  contents: read
 22
 23jobs:
 24  bump:
 25    runs-on: ubuntu-latest
 26    steps:
 27      - name: Determine version
 28        id: ver
 29        run: |
 30          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
 31            VERSION="${{ inputs.version }}"
 32          else
 33            TAG="${{ github.event.release.tag_name }}"
 34            VERSION="${TAG#v}"
 35          fi
 36          # Skip nightly / preview tags
 37          if [[ "$VERSION" == nightly* || "$VERSION" == preview* ]]; then
 38            echo "Skipping non-stable release: $VERSION"
 39            echo "skip=true" >> $GITHUB_OUTPUT
 40          else
 41            echo "skip=false" >> $GITHUB_OUTPUT
 42          fi
 43          echo "version=$VERSION" >> $GITHUB_OUTPUT
 44
 45      - name: Install Nix
 46        if: steps.ver.outputs.skip != 'true'
 47        uses: cachix/install-nix-action@v31
 48        with:
 49          extra_nix_config: |
 50            experimental-features = nix-command flakes
 51
 52      - name: Checkout nixpkgs fork
 53        if: steps.ver.outputs.skip != 'true'
 54        uses: actions/checkout@v6
 55        with:
 56          repository: floatpane/nixpkgs
 57          token: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
 58          path: nixpkgs
 59          fetch-depth: 0
 60
 61      - name: Sync fork with upstream master
 62        if: steps.ver.outputs.skip != 'true'
 63        working-directory: nixpkgs
 64        run: |
 65          git config user.name "Floatpane Bot"
 66          git config user.email "us@floatpane.com"
 67          git remote add upstream https://github.com/NixOS/nixpkgs.git
 68          git fetch upstream master staging
 69          git checkout master
 70          git reset --hard upstream/master
 71          git push origin master --force-with-lease
 72
 73      - name: Get current version (from master)
 74        if: steps.ver.outputs.skip != 'true'
 75        id: current
 76        working-directory: nixpkgs
 77        run: |
 78          PKG=pkgs/by-name/ma/matcha/package.nix
 79          OLD=$(grep -E '^\s*version\s*=\s*"' "$PKG" | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
 80          echo "old=$OLD" >> $GITHUB_OUTPUT
 81
 82      - name: Write go overlay from staging
 83        if: steps.ver.outputs.skip != 'true'
 84        working-directory: nixpkgs
 85        run: |
 86          # master nixpkgs heavily cached. Staging has go_1_26 = 1.26.3.
 87          # Overlay swaps only go_1_26 → minimal rebuild.
 88          STAGING_REV=$(git rev-parse upstream/staging)
 89          echo "STAGING_REV=$STAGING_REV" >> $GITHUB_ENV
 90          cat > /tmp/go-overlay.nix <<EOF
 91          let
 92            staging = import (builtins.fetchTarball
 93              "https://github.com/NixOS/nixpkgs/archive/$STAGING_REV.tar.gz") {};
 94          in final: prev: {
 95            go_1_26 = staging.go_1_26;
 96            go = staging.go_1_26;
 97            buildGoModule = prev.buildGoModule.override { go = staging.go_1_26; };
 98          }
 99          EOF
100          cat /tmp/go-overlay.nix
101
102      - name: Create bump branch
103        if: steps.ver.outputs.skip != 'true'
104        working-directory: nixpkgs
105        run: |
106          BRANCH="matcha-${{ steps.ver.outputs.version }}"
107          git checkout -b "$BRANCH"
108          echo "BRANCH=$BRANCH" >> $GITHUB_ENV
109
110      - name: Bump version and reset hashes
111        if: steps.ver.outputs.skip != 'true'
112        working-directory: nixpkgs
113        run: |
114          PKG=pkgs/by-name/ma/matcha/package.nix
115          NEW="${{ steps.ver.outputs.version }}"
116          # Replace version line
117          sed -i -E "s/(version\s*=\s*\")[^\"]+(\")/\1$NEW\2/" "$PKG"
118          # Reset src hash + vendorHash to fakeHash so nix build prints real ones
119          sed -i -E 's|hash = "sha256-[A-Za-z0-9+/=]+"|hash = lib.fakeHash|' "$PKG"
120          sed -i -E 's|vendorHash = "sha256-[A-Za-z0-9+/=]+"|vendorHash = lib.fakeHash|' "$PKG"
121
122      - name: Prefetch src hash (no build)
123        if: steps.ver.outputs.skip != 'true'
124        id: src_hash
125        working-directory: nixpkgs
126        run: |
127          NEW="${{ steps.ver.outputs.version }}"
128          nix-shell -p nix-prefetch-github --run \
129            "nix-prefetch-github floatpane matcha --rev v$NEW --json" \
130            > /tmp/prefetch.json
131          cat /tmp/prefetch.json
132          # nix-prefetch-github returns base32 sha256; convert to SRI sha256-...
133          RAW=$(jq -r .hash /tmp/prefetch.json)
134          if [ -z "$RAW" ] || [ "$RAW" = "null" ]; then
135            # Older nix-prefetch-github uses .sha256
136            RAW=$(jq -r .sha256 /tmp/prefetch.json)
137            HASH=$(nix hash to-sri --type sha256 "$RAW")
138          else
139            HASH="$RAW"
140          fi
141          echo "Resolved SRI hash: $HASH"
142          echo "hash=$HASH" >> $GITHUB_OUTPUT
143          sed -i -E "s|hash = lib.fakeHash|hash = \"$HASH\"|" pkgs/by-name/ma/matcha/package.nix
144
145      - name: Build to extract vendorHash
146        if: steps.ver.outputs.skip != 'true'
147        working-directory: nixpkgs
148        run: |
149          set +e
150          nix-build ./. -A matcha --no-out-link \
151            --arg overlays "[ (import /tmp/go-overlay.nix) ]" \
152            2>&1 | tee /tmp/build-vendor.log
153          HASH=$(grep -oE 'got:[[:space:]]+sha256-[A-Za-z0-9+/=]+' /tmp/build-vendor.log | head -1 | awk '{print $2}')
154          if [ -z "$HASH" ]; then
155            echo "Failed to extract vendorHash"; exit 1
156          fi
157          sed -i -E "s|vendorHash = lib.fakeHash|vendorHash = \"$HASH\"|" pkgs/by-name/ma/matcha/package.nix
158
159      - name: Final build (sanity check)
160        if: steps.ver.outputs.skip != 'true'
161        working-directory: nixpkgs
162        run: |
163          nix-build ./. -A matcha --no-out-link \
164            --arg overlays "[ (import /tmp/go-overlay.nix) ]"
165
166      - name: Commit and push
167        if: steps.ver.outputs.skip != 'true'
168        working-directory: nixpkgs
169        run: |
170          git add pkgs/by-name/ma/matcha/package.nix
171          git commit -m "matcha: ${{ steps.current.outputs.old }} -> ${{ steps.ver.outputs.version }}"
172          git push -u origin "$BRANCH" --force-with-lease
173
174      - name: Open PR against NixOS/nixpkgs
175        if: steps.ver.outputs.skip != 'true'
176        env:
177          GH_TOKEN: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
178        working-directory: nixpkgs
179        run: |
180          BODY=$(cat <<EOF
181          ## Description
182
183          Automated version bump for \`matcha\` email client.
184
185          - Old: ${{ steps.current.outputs.old }}
186          - New: ${{ steps.ver.outputs.version }}
187          - Upstream release: https://github.com/floatpane/matcha/releases/tag/v${{ steps.ver.outputs.version }}
188
189          ## Things done
190
191          - Built on \`x86_64-linux\` via GitHub Actions
192          - Hashes regenerated from upstream tarball
193          - No package metadata changes beyond version + hashes
194
195          cc @andrinoff
196          EOF
197          )
198          gh pr create \
199            --repo NixOS/nixpkgs \
200            --base master \
201            --head "floatpane:$BRANCH" \
202            --title "matcha: ${{ steps.current.outputs.old }} -> ${{ steps.ver.outputs.version }}" \
203            --body "$BODY"