name: Sync Linguist
on: 
  workflow_dispatch:
    inputs:
      linguist_tag:
        description: 'Linguist tag override'
        required: False
        default: ''
  schedule:
    # Run once a day to check for new Linguist updates automatically
    - cron:  '0 20 * * *'

jobs:
  sync-linguist:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-go@v5
    - uses: actions/checkout@v2
    - name: Find previous Linguist commit
      id: previous_linguist
      run: |
        set -euo pipefail
        IFS=$'\n\t'
        commit=$(sed --quiet --regexp-extended 's/[[:space:]]+commit[[:space:]]+=[[:space:]]"([a-f0-9]{40})"/\1/p' internal/code-generator/generator/generator_test.go)
        echo "::set-output name=commit::$commit"
        echo "::set-output name=short_commit::${commit::8}"
    - uses: actions/checkout@v2
      with:
        repository: github/linguist
        path: .linguist
        fetch-depth: 0
    - name: check out latest release
      id: linguist-release
      # the `grep -v "-"` is to exclude any pre-release versions.
      # Linguist doesn't have any right now, but just in case.
      run: |
        set -euo pipefail
        IFS=$'\n\t'        
        cd .linguist
        if [[ -n "${{ github.event.inputs.linguist_tag }}" ]]; then
          echo "Using tag override '${{ github.event.inputs.linguist_tag }}'"
          latest="${{ github.event.inputs.linguist_tag }}"
        else
          latest=$(git tag --list | \
                     grep -v "-" | \
                     sort --version-sort --reverse | \
                     head -1)
        fi

        if [[ -z "$latest" ]]; then
          echo "could not determine latest Linguist version"
          exit 1
        fi

        echo "::set-output name=linguist_version::$latest"
        git checkout $latest
      
        commit=$(git rev-parse HEAD)
        if [[ -z "$commit" ]]; then
          echo "could not determine latest Linguist commit"
          exit 1
        fi

        echo "::set-output name=commit::$commit"
        echo "::set-output name=short_commit::${commit::8}"

        cd ..
    - name: Update Linguist information
      run: |
        set -euo pipefail
        IFS=$'\n\t'

        sed --in-place --regexp-extended 's/(commit[[:space:]]+=[[:space:]])("[a-f0-9]{40}")/\1"${{ steps.linguist-release.outputs.commit }}"/' internal/code-generator/generator/generator_test.go
        sed --in-place --regexp-extended 's/version \*\*v.+\*\*\./version \*\*${{ steps.linguist-release.outputs.linguist_version }}\*\*\./' README.md
    - name: Generate code
      run: make code-generate
    - name: Commit changes
      id: commit
      run: |
        set -euo pipefail
        IFS=$'\n\t'
        echo "git current state:"
        git status

        branch_name="feature/sync-linguist-${{ steps.previous_linguist.outputs.short_commit }}"
        if git rev-parse --quiet --verify $branch_name; then
          echo "Linguist update branch $branch_name already exists"
          echo "::set-output name=needs_pr::true"
          exit 0
        fi

        if [[ -n "$(git status --porcelain)" ]]; then
          echo "Creating branch $branch_name for PR"
          git checkout -b $branch_name
          echo "::set-output name=branch_name::$branch_name"
          echo "Creating Linguist update commit"
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add .
          git commit -m "Updated Linguist to ${{ steps.linguist-release.outputs.linguist_version }}"
          git push --set-upstream origin $branch_name
          echo "Changes committed. Will create PR."
          echo "::set-output name=needs_pr::true"
          exit 0
        fi
          
        echo "Linguist update unnecessary"
        echo "::set-output name=needs_pr::false"
    - name: Create Pull Request
      id: open-pr
      uses: repo-sync/pull-request@v2
      if: ${{ steps.commit.outputs.needs_pr == 'true' }}
      with:
        source_branch: ${{ steps.commit.outputs.branch_name }}
        pr_title: "Update Linguist to ${{ steps.linguist-release.outputs.linguist_version }}"
        pr_body: |
          Automated Linguist update :robot:

          This PR updates Linguist from [${{ steps.previous_linguist.outputs.short_commit }}](https://github.com/github/linguist/commit/${{ steps.previous_linguist.outputs.commit }}) to [${{ steps.linguist-release.outputs.linguist_version }}](https://github.com/github/linguist/releases/tag/${{  steps.linguist-release.outputs.linguist_version }}) ([${{ steps.linguist-release.outputs.short_commit }}](https://github.com/github/linguist/commit/${{ steps.linguist-release.outputs.commit }}))

          * [Linguist release notes](https://github.com/github/linguist/releases/tag/${{ steps.linguist-release.outputs.linguist_version }})
          * [Compare Linguist code changes](https://github.com/github/linguist/compare/${{ steps.previous_linguist.outputs.commit }}...${{ steps.linguist-release.outputs.linguist_version }})
        destination_branch: "master"
        github_token: ${{ secrets.GITHUB_TOKEN }}
    - name: output-url
      if: ${{ steps.commit.outputs.needs_pr == 'true' }}
      run: echo ${{ steps.open-pr.outputs.pr_url }}
    - name: No PR Created
      if: ${{ steps.commit.needs_pr != 'true' }}
      run: echo "No changes for ${{ steps.linguist-release.outputs.linguist_version }}"
