Skip to content
edgesync Artifact [9f114bcfca]
Login

Artifact [9f114bcfca]

Artifact 9f114bcfca0e89769b349c7b9a929c4c27a03e73a66def7807e02e908789a3e2:


name: Bump upstream
on:
  repository_dispatch:
    types: [upstream-bump]
  workflow_dispatch:
    inputs:
      repo:        { required: true,  type: string }
      module_path: { required: true,  type: string }
      version:     { required: true,  type: string }
      release_url: { required: false, type: string }
      tag_sha:     { required: false, type: string }
      actor:       { required: false, type: string }

permissions:
  contents: write
  pull-requests: write

jobs:
  bump:
    runs-on: ubuntu-latest
    env:
      EXPECTED_REPO: libfossil
      EXPECTED_MODULE: github.com/danmestas/libfossil
    steps:
      - name: Resolve inputs
        id: in
        env:
          PAYLOAD_REPO: ${{ github.event.client_payload.repo }}
          PAYLOAD_MODULE: ${{ github.event.client_payload.module_path }}
          PAYLOAD_VERSION: ${{ github.event.client_payload.version }}
          PAYLOAD_RELEASE_URL: ${{ github.event.client_payload.release_url }}
          PAYLOAD_TAG_SHA: ${{ github.event.client_payload.tag_sha }}
          PAYLOAD_ACTOR: ${{ github.event.client_payload.actor }}
          INPUT_REPO: ${{ inputs.repo }}
          INPUT_MODULE: ${{ inputs.module_path }}
          INPUT_VERSION: ${{ inputs.version }}
          INPUT_RELEASE_URL: ${{ inputs.release_url }}
          INPUT_TAG_SHA: ${{ inputs.tag_sha }}
          INPUT_ACTOR: ${{ inputs.actor }}
        run: |
          REPO="${PAYLOAD_REPO:-$INPUT_REPO}"
          MODULE_PATH="${PAYLOAD_MODULE:-$INPUT_MODULE}"
          VERSION="${PAYLOAD_VERSION:-$INPUT_VERSION}"
          RELEASE_URL="${PAYLOAD_RELEASE_URL:-$INPUT_RELEASE_URL}"
          TAG_SHA="${PAYLOAD_TAG_SHA:-$INPUT_TAG_SHA}"
          ACTOR="${PAYLOAD_ACTOR:-${INPUT_ACTOR:-${{ github.actor }}}}"

          if [[ "$REPO" != "$EXPECTED_REPO" ]]; then
            echo "::notice::Ignoring dispatch for repo=$REPO (expected $EXPECTED_REPO)"
            echo "skip=true" >> "$GITHUB_OUTPUT"
            exit 0
          fi
          if [[ "$MODULE_PATH" != "$EXPECTED_MODULE" ]]; then
            echo "::error::module_path mismatch: got '$MODULE_PATH', expected '$EXPECTED_MODULE'"
            exit 1
          fi
          if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then
            echo "::error::bad version: '$VERSION'"
            exit 1
          fi

          {
            echo "repo=$REPO"
            echo "module=$MODULE_PATH"
            echo "version=$VERSION"
            echo "release_url=$RELEASE_URL"
            echo "tag_sha=$TAG_SHA"
            echo "actor=$ACTOR"
            echo "branch=chore/bump-${REPO}-${VERSION}"
          } >> "$GITHUB_OUTPUT"

      - name: Idempotency check
        if: steps.in.outputs.skip != 'true'
        id: idem
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          BRANCH: ${{ steps.in.outputs.branch }}
        run: |
          if gh pr list --repo "${{ github.repository }}" --head "$BRANCH" --state open --json number -q '.[0].number' | grep -q .; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
            echo "::notice::PR already open for $BRANCH; skipping"
          fi

      - if: steps.in.outputs.skip != 'true' && steps.idem.outputs.exists != 'true'
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - if: steps.in.outputs.skip != 'true' && steps.idem.outputs.exists != 'true'
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod

      - if: steps.in.outputs.skip != 'true' && steps.idem.outputs.exists != 'true'
        name: Bump module
        id: bump
        env:
          BRANCH: ${{ steps.in.outputs.branch }}
          MODULE: ${{ steps.in.outputs.module }}
          VERSION: ${{ steps.in.outputs.version }}
        run: |
          git switch -c "$BRANCH"
          for i in 1 2 3; do
            if go get "${MODULE}@${VERSION}"; then
              break
            fi
            if [ "$i" -lt 3 ]; then
              echo "::notice::go get failed (attempt $i/3) — likely GOPROXY propagation race; retrying in 15s..."
              sleep 15
            else
              echo "::error::go get failed after 3 attempts"
              exit 1
            fi
          done
          go mod tidy
          if git diff --quiet go.mod go.sum; then
            echo "::notice::No-op bump — version already pinned"
            echo "noop=true" >> "$GITHUB_OUTPUT"
          fi

      - if: steps.in.outputs.skip != 'true' && steps.idem.outputs.exists != 'true' && steps.bump.outputs.noop != 'true'
        name: Verify build
        run: go build ./...

      - if: steps.in.outputs.skip != 'true' && steps.idem.outputs.exists != 'true' && steps.bump.outputs.noop != 'true'
        name: Commit + push + open PR
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          BRANCH: ${{ steps.in.outputs.branch }}
          REPO: ${{ steps.in.outputs.repo }}
          VERSION: ${{ steps.in.outputs.version }}
          MODULE: ${{ steps.in.outputs.module }}
          RELEASE_URL: ${{ steps.in.outputs.release_url }}
          TAG_SHA: ${{ steps.in.outputs.tag_sha }}
          ACTOR: ${{ steps.in.outputs.actor }}
        run: |
          git config user.name  "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add go.mod go.sum
          git commit -m "chore: bump ${REPO} → ${VERSION}"
          git push -u origin "$BRANCH"
          gh pr create \
            --title "chore: bump ${REPO} → ${VERSION}" \
            --body "Auto-bump from upstream release.

          - Module: \`${MODULE}\`
          - Version: \`${VERSION}\`
          - Upstream release: ${RELEASE_URL}
          - Tag SHA: \`${TAG_SHA}\`
          - Triggered by: @${ACTOR}

          CI must pass before merge. Review go.sum diff for transitive surprises."