---
name: Update flake inputs

on:
  schedule:
    - cron: "0 0 1 * *"
  workflow_dispatch:

defaults:
  run:
    shell: bash

jobs:
  flake-update:
    runs-on: ubuntu-24.04
    if: vars.APP_ID
    strategy:
      matrix:
        branch: [master, release-25.11]
    steps:
      - id: generate-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ vars.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}
          permission-contents: write
          permission-pull-requests: write

      - uses: actions/checkout@v6
        with:
          ref: ${{ matrix.branch }}
          token: ${{ steps.generate-token.outputs.token }}

      - uses: cachix/install-nix-action@v31

      - id: user-info
        env:
          GH_TOKEN: ${{ steps.generate-token.outputs.token }}
          slug: ${{ steps.generate-token.outputs.app-slug }}
        run: |
          name="$slug[bot]"
          id="$(gh api "/users/$name" --jq .id)"
          printf \
            '%s=%s\n' \
            id "$id" \
            name "$name" \
            email "$id+$name@users.noreply.github.com" \
            >>"$GITHUB_OUTPUT"

      - name: setup git
        env:
          name: ${{ steps.user-info.outputs.name }}
          email: ${{ steps.user-info.outputs.email }}
        run: |
          git config --global user.name "$name"
          git config --global user.email "$email"

      - name: update lock files
        run: |
          nix flake update &
          nix flake update --flake ./flake/dev &

          wait

          git add {,flake/dev/}flake.lock

          # The nixpkgs maintainers may have changed, so keep all-maintainers
          # in sync
          if nix run .#all-maintainers; then
            git add generated/all-maintainers.nix
          else
            echo "::error::failed to update generated/all-maintainers.nix"
          fi

          git commit --message "flake: update all inputs"

      - name: create pull request
        env:
          GH_TOKEN: ${{ steps.generate-token.outputs.token }}
          base_branch: ${{ matrix.branch }}
          body: "This is an automated update triggered by the [workflow run #${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})."  # yamllint disable-line rule:line-length
          label: "topic: dependencies"
          pr_branch: update_flake_lock_action_${{ matrix.branch }}
          title: "${{ startsWith(matrix.branch, 'release') && format('[{0}] ', matrix.branch) || '' }}flake: update all inputs"  # yamllint disable-line rule:line-length
        run: |
          git switch --create "$pr_branch"
          git push origin "$pr_branch" --force --set-upstream

          pr_count="$(
            gh api \
              --method GET \
              "/repos/$GITHUB_REPOSITORY/pulls" \
              --field per_page=1 \
              --raw-field head="$GITHUB_REPOSITORY_OWNER:$pr_branch" \
              --jq length
          )"

          if ((pr_count)); then
            gh pr edit \
              --add-label "$label" \
              --body "$body" \
              --title "$title"

          else
            gh pr create \
              --base "$base_branch" \
              --body "$body" \
              --label "$label" \
              --title "$title"
          fi
