# This workflows polls releases from actions/runner and in case of a new one it
# updates files containing runner version and opens a pull request.
name: Runner Updates Check (Scheduled Job)

on:
  schedule:
    # run daily
    - cron: "0 9 * * *"
  workflow_dispatch:

jobs:
  # check_versions compares our current version and the latest available runner
  # version and sets them as outputs.
  check_versions:
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ github.token }}
    outputs:
      runner_current_version: ${{ steps.runner_versions.outputs.runner_current_version }}
      runner_latest_version: ${{ steps.runner_versions.outputs.runner_latest_version }}
      container_hooks_current_version: ${{ steps.container_hooks_versions.outputs.container_hooks_current_version }}
      container_hooks_latest_version: ${{ steps.container_hooks_versions.outputs.container_hooks_latest_version }}
    steps:
      - uses: actions/checkout@v3

      - name: Get runner current and latest versions
        id: runner_versions
        run: |
          CURRENT_VERSION="$(echo -n $(cat runner/VERSION | grep 'RUNNER_VERSION=' | cut -d '=' -f2))"
          echo "Current version: $CURRENT_VERSION"
          echo runner_current_version=$CURRENT_VERSION >> $GITHUB_OUTPUT

          LATEST_VERSION=$(gh release list --exclude-drafts --exclude-pre-releases --limit 1 -R actions/runner | grep -oP '(?<=v)[0-9.]+' | head -1)
          echo "Latest version: $LATEST_VERSION"
          echo runner_latest_version=$LATEST_VERSION >> $GITHUB_OUTPUT

      - name: Get container-hooks current and latest versions
        id: container_hooks_versions
        run: |
          CURRENT_VERSION="$(echo -n $(cat runner/VERSION | grep 'RUNNER_CONTAINER_HOOKS_VERSION=' | cut -d '=' -f2))"
          echo "Current version: $CURRENT_VERSION"
          echo container_hooks_current_version=$CURRENT_VERSION >> $GITHUB_OUTPUT

          LATEST_VERSION=$(gh release list --exclude-drafts --exclude-pre-releases --limit 1 -R actions/runner-container-hooks | grep -oP '(?<=v)[0-9.]+' | head -1)
          echo "Latest version: $LATEST_VERSION"
          echo container_hooks_latest_version=$LATEST_VERSION >> $GITHUB_OUTPUT

  # check_pr checks if a PR for the same update already exists. It only runs if
  # runner latest version != our current version. If no existing PR is found,
  # it sets a PR name as output.
  check_pr:
    runs-on: ubuntu-latest
    needs: check_versions
    if: needs.check_versions.outputs.runner_current_version != needs.check_versions.outputs.runner_latest_version || needs.check_versions.outputs.container_hooks_current_version != needs.check_versions.outputs.container_hooks_latest_version
    outputs:
      pr_name: ${{ steps.pr_name.outputs.pr_name }}
    env:
      GH_TOKEN: ${{ github.token }}
    steps:
      - name: debug
        run:
          echo "RUNNER_CURRENT_VERSION=${{ needs.check_versions.outputs.runner_current_version }}"
          echo "RUNNER_LATEST_VERSION=${{ needs.check_versions.outputs.runner_latest_version }}"
          echo "CONTAINER_HOOKS_CURRENT_VERSION=${{ needs.check_versions.outputs.container_hooks_current_version }}"
          echo "CONTAINER_HOOKS_LATEST_VERSION=${{ needs.check_versions.outputs.container_hooks_latest_version }}"

      - uses: actions/checkout@v3

      - name: PR Name
        id: pr_name
        env:
          RUNNER_CURRENT_VERSION: ${{ needs.check_versions.outputs.runner_current_version }}
          RUNNER_LATEST_VERSION: ${{ needs.check_versions.outputs.runner_latest_version }}
          CONTAINER_HOOKS_CURRENT_VERSION: ${{ needs.check_versions.outputs.container_hooks_current_version }}
          CONTAINER_HOOKS_LATEST_VERSION: ${{ needs.check_versions.outputs.container_hooks_latest_version }}
        # Generate a PR name with the following title:
        # Updates: runner to v2.304.0 and container-hooks to v0.3.1
        run: |
          RUNNER_MESSAGE="runner to v${RUNNER_LATEST_VERSION}"
          CONTAINER_HOOKS_MESSAGE="container-hooks to v${CONTAINER_HOOKS_LATEST_VERSION}"

          PR_NAME="Updates:"
          if [ "$RUNNER_CURRENT_VERSION" != "$RUNNER_LATEST_VERSION" ]
          then
            PR_NAME="$PR_NAME $RUNNER_MESSAGE"
          fi
          if [ "$CONTAINER_HOOKS_CURRENT_VERSION" != "$CONTAINER_HOOKS_LATEST_VERSION" ]
          then
            PR_NAME="$PR_NAME $CONTAINER_HOOKS_MESSAGE"
          fi

          result=$(gh pr list --search "$PR_NAME" --json number --jq ".[].number" --limit 1)
          if [ -z "$result" ]
          then
            echo "No existing PRs found, setting output with pr_name=$PR_NAME"
            echo pr_name=$PR_NAME >> $GITHUB_OUTPUT
          else
            echo "Found a PR with title '$PR_NAME' already existing: ${{ github.server_url }}/${{ github.repository }}/pull/$result"
          fi

  # update_version updates runner version in the files listed below, commits
  # the changes and opens a pull request as `github-actions` bot.
  update_version:
    runs-on: ubuntu-latest
    needs:
      - check_versions
      - check_pr
    if: needs.check_pr.outputs.pr_name
    permissions:
      pull-requests: write
      contents: write
      actions: write
    env:
      GH_TOKEN: ${{ github.token }}
      RUNNER_CURRENT_VERSION: ${{ needs.check_versions.outputs.runner_current_version }}
      RUNNER_LATEST_VERSION: ${{ needs.check_versions.outputs.runner_latest_version }}
      CONTAINER_HOOKS_CURRENT_VERSION: ${{ needs.check_versions.outputs.container_hooks_current_version }}
      CONTAINER_HOOKS_LATEST_VERSION: ${{ needs.check_versions.outputs.container_hooks_latest_version }}
      PR_NAME: ${{ needs.check_pr.outputs.pr_name }}

    steps:
      - uses: actions/checkout@v3

      - name: New branch
        run: git checkout -b update-runner-"$(date +%Y-%m-%d)"

      - name: Update files
        run: |
          CURRENT_VERSION="${RUNNER_CURRENT_VERSION//./\\.}"
          LATEST_VERSION="${RUNNER_LATEST_VERSION//./\\.}"
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/VERSION
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/Makefile
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" Makefile
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" test/e2e/e2e_test.go

          CURRENT_VERSION="${CONTAINER_HOOKS_CURRENT_VERSION//./\\.}"
          LATEST_VERSION="${CONTAINER_HOOKS_LATEST_VERSION//./\\.}"
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/VERSION
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/Makefile
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" Makefile
          sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" test/e2e/e2e_test.go

      - name: Commit changes
        run: |
          # from https://github.com/orgs/community/discussions/26560
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git config user.name "github-actions[bot]"
          git add .
          git commit -m "$PR_NAME"
          git push -u origin HEAD

      - name: Create pull request
        run: gh pr create -f -l "runners update"
