Bump Go Version #126
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: Bump Go Version | |
| on: | |
| schedule: | |
| - cron: "0 8 * * *" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| id-token: write | |
| jobs: | |
| bump-go-version: | |
| name: Bump Go Version | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.0 | |
| - name: Fetch ephemeral GitHub token | |
| id: fetch-token | |
| uses: elastic/ci-gh-actions/fetch-github-token@8a7604dfdd4e7fe21f969bfe9ff96e17635ea577 # v1.0.0 | |
| with: | |
| vault-instance: "ci-prod" | |
| - name: Determine Go versions | |
| id: go-versions | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # Determine the latest stable Go minor, and the penultimate stable Go minor. | |
| # For the penultimate minor, we also need its latest patch (for toolchain). | |
| latest_two=$( | |
| curl -fsSL https://go.dev/dl/?mode=json \ | |
| | jq -r '.[] | select(.stable == true) | .version | sub("^go";"")' \ | |
| | sort -Vr \ | |
| | awk -F. ' | |
| { | |
| minor = $1 "." $2 | |
| if (!(minor in seen)) { | |
| seen[minor] = $0 | |
| print minor "\t" $0 | |
| } | |
| } | |
| ' \ | |
| | head -n 2 | |
| ) | |
| latest1_minor=$(echo "$latest_two" | awk 'NR==1{print $1}') | |
| latest2_minor=$(echo "$latest_two" | awk 'NR==2{print $1}') | |
| latest2_patch=$(echo "$latest_two" | awk 'NR==2{print $2}') | |
| target_minor=$latest2_minor | |
| target_patch=$latest2_patch | |
| desired_toolchain="go${target_patch}" | |
| if [[ -z "${latest1_minor}" || -z "${latest2_minor}" || -z "${latest2_patch}" ]]; then | |
| echo "Failed to determine Go versions from go.dev" >&2 | |
| exit 1 | |
| fi | |
| # List all go.mod files, ignoring any transient permission errors from find. | |
| mapfile -t go_mod_files < <(find . -name go.mod -print 2>/dev/null | sort) | |
| needs_update=false | |
| updates=() | |
| updated_files=() | |
| root_go_changed=false | |
| for mod_file in "${go_mod_files[@]}"; do | |
| current_go=$(awk '/^go / {print $2; exit}' "$mod_file") | |
| current_minor=$(echo "${current_go}" | awk -F. '{print $1 "." $2}') | |
| current_toolchain=$(awk '/^toolchain / {print $2; exit}' "$mod_file" || true) | |
| module_changed=false | |
| go_from="${current_go}" | |
| go_to="${current_go}" | |
| toolchain_from="${current_toolchain}" | |
| if [[ -z "${toolchain_from}" ]]; then | |
| toolchain_from="(missing)" | |
| fi | |
| # Update the go directive only when the minor differs. Preserve formatting (go 1.x vs go 1.x.y). | |
| if [[ "${current_minor}" != "${target_minor}" ]]; then | |
| if [[ "${current_go}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| go_to="${target_minor}.0" | |
| else | |
| go_to="${target_minor}" | |
| fi | |
| sed -i -e "s/^go .*/go ${go_to}/" "$mod_file" | |
| module_changed=true | |
| # Only treat this as a breaking change when the root module's go directive changes | |
| # (ie. a Go minor bump), not when only toolchain patch changes. | |
| if [[ "${mod_file#./}" == "go.mod" ]]; then | |
| root_go_changed=true | |
| fi | |
| fi | |
| # Always enforce toolchain for the target patch (update or insert). | |
| if [[ "${current_toolchain}" != "${desired_toolchain}" ]]; then | |
| if grep -q '^toolchain ' "$mod_file"; then | |
| sed -i -e "s/^toolchain .*/toolchain ${desired_toolchain}/" "$mod_file" | |
| else | |
| sed -i -e "/^go /a toolchain ${desired_toolchain}" "$mod_file" | |
| fi | |
| module_changed=true | |
| fi | |
| if [[ "${module_changed}" == "true" ]]; then | |
| updates+=("| \`${mod_file#./}\` | \`${go_from}\` -> \`${go_to}\` | \`${toolchain_from}\` -> \`${desired_toolchain}\` |") | |
| updated_files+=("${mod_file#./}") | |
| needs_update=true | |
| fi | |
| done | |
| if [[ "$needs_update" == "false" ]]; then | |
| echo "needs_update=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| { | |
| echo "needs_update=true" | |
| echo "latest1=$latest1_minor" | |
| echo "latest2=$latest2_minor" | |
| echo "target_minor=$target_minor" | |
| echo "target_patch=$target_patch" | |
| echo "target=$target_patch" | |
| if [[ "${root_go_changed}" == "true" ]]; then | |
| echo "commit_type=feat!" | |
| else | |
| echo "commit_type=chore" | |
| fi | |
| echo "updated_modules<<EOF" | |
| for entry in "${updates[@]}"; do echo "$entry"; done | |
| echo "EOF" | |
| echo "updated_files<<EOF" | |
| for entry in "${updated_files[@]}"; do | |
| echo "$entry" | |
| done | |
| echo "EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Set up Go | |
| if: steps.go-versions.outputs.needs_update == 'true' | |
| uses: actions/setup-go@v2.1.3 | |
| with: | |
| go-version: ${{ steps.go-versions.outputs.target_patch }} | |
| - name: Update go.mod and tidy | |
| if: steps.go-versions.outputs.needs_update == 'true' | |
| shell: bash | |
| env: | |
| GOTOOLCHAIN: go${{ steps.go-versions.outputs.target_patch }} | |
| run: | | |
| set -euo pipefail | |
| while IFS= read -r mod_file; do | |
| [[ -z "$mod_file" ]] && continue | |
| mod_dir=$(dirname "$mod_file") | |
| (cd "$mod_dir" && go mod tidy) | |
| done <<'EOF' | |
| ${{ steps.go-versions.outputs.updated_files }} | |
| EOF | |
| - name: Create PR | |
| if: steps.go-versions.outputs.needs_update == 'true' | |
| uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 | |
| with: | |
| token: ${{ steps.fetch-token.outputs.token }} | |
| commit-message: "${{ steps.go-versions.outputs.commit_type }}: bump go version to ${{ steps.go-versions.outputs.target }}" | |
| committer: "Elastic Machine <elasticmachine@users.noreply.github.com>" | |
| author: "Elastic Machine <elasticmachine@users.noreply.github.com>" | |
| branch: "go-version-bump--branches--main" | |
| delete-branch: true | |
| base: main | |
| title: "${{ steps.go-versions.outputs.commit_type }}: bump go version to ${{ steps.go-versions.outputs.target }}" | |
| body: | | |
| Bumps Go version to ${{ steps.go-versions.outputs.target }}. | |
| Updated go.mod files: | |
| | Module | go | toolchain | | |
| | --- | --- | --- | | |
| ${{ steps.go-versions.outputs.updated_modules }} |