Skip to content

Commit

Permalink
tools/gomod-updater: Fix Go Dependabot PR's automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrus committed Oct 16, 2023
1 parent 6da45b8 commit 3b9783c
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 0 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/ci-dependabot-fixup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# NOTE: This name appears in GitHub's Checks API and in workflow's status badge.
name: ci-dependabot-fixup

# Trigger the workflow when:
on:
# When a pull request event occurs for a pull request against one of the
# matched branches.
pull_request:
types: [opened, synchronize, reopened]
branches:
- main

# Cancel in-progress jobs on same branch.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
check-dependabot:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: "0"

- name: Ensure Dependebot author
id: check
run: |
# Ensure Dependabot author.
if [ "${{ github.event.pull_request.user.login }}" != "dependabot[bot]" ]; then
echo "This PR was not created by Dependabot. No further action is being taken."
echo "::set-output name=skip::true"
exit 0;
fi
# Ensure only Dependabot commits.
git fetch --no-tags origin +refs/heads/${BASE_BRANCH}:refs/remotes/origin/${BASE_BRANCH}
if git log origin/${BASE_BRANCH}..HEAD --pretty=format:'%an' | grep -v '^dependabot\[bot\]$' | grep -q .
then
echo "This PR has commits not by Dependabot."
echo "::set-output name=skip::true"
exit 0;
fi
echo "All commits are by Dependabot."
env:
BASE_BRANCH: ${{ github.base_ref }}

- name: Set up Go
if: steps.check.outputs.skip != 'true'
uses: actions/setup-go@v4
with:
go-version: "1.21.x"

- name: Build gomod updater
if: steps.check.outputs.skip != 'true'
working-directory: tools/gomod-updater
run: go build

# Dependabot titles are:
# <prefix>: bump <dependancy name> from <frmo_version> to <to_version> in <path>
# e.g. client-sdk/go: bump github.com/ethereum/go-ethereum from 1.12.1 to 1.13.3 in /client-sdk/go
# as long as the (configurable) <prefix> is without whitespace, the bellow parsing should work.
- name: Try extracting package name and version
if: steps.check.outputs.skip != 'true'
id: extract
run: |
title="${{ github.event.pull_request.title }}"
repo=$(echo $title | awk '{print $3}')
version=$(echo $title | awk '{print $7}')
# Set the output variables for subsequent steps
echo "::set-output name=repo::$repo"
echo "::set-output name=version::$version"
- name: Run gomod updater
if: steps.check.outputs.skip != 'true'
run: |
file_list=$(find . -type f -name 'go.mod' | awk -vORS=, '{ print $1 }' | sed 's/,$/\n/')
tools/gomod-updater/gomod-updater ${{ steps.extract.outputs.repo }} ${{ steps.extract.outputs.version }} --packages "$file_list"
- name: Commit and push all changed files
if: steps.check.outputs.skip != 'true'
env:
CI_COMMIT_MESSAGE: Dependabot dependencies fixup 👷
CI_COMMIT_AUTHOR: Dependabot Corrector
run: |
git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}"
git config --global user.email "[email protected]"
git commit -a -m "${{ env.CI_COMMIT_MESSAGE }}"
git push
4 changes: 4 additions & 0 deletions .github/workflows/ci-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ jobs:
working-directory: tools/gen_runtime_vectors
run: go build

- name: Test build gomod updater
working-directory: tools/gomod-updater
run: go build

typecheck:
# NOTE: This name appears in GitHub's Checks API.
name: typecheck
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ tests/benchmark/benchmark
client-sdk/ts-web/core/reflect-go/reflect-go
tools/gen_runtime_vectors/gen_runtime_vectors
tools/orc/orc
tools/gomod-updater/gomod-updater
13 changes: 13 additions & 0 deletions tools/gomod-updater/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/oasisprotocol/oasis-sdk/tools/gomod-updater

go 1.21

toolchain go1.21.2

require (
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
golang.org/x/mod v0.13.0
)

require github.com/inconshreveable/mousetrap v1.1.0 // indirect
12 changes: 12 additions & 0 deletions tools/gomod-updater/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
77 changes: 77 additions & 0 deletions tools/gomod-updater/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package main

import (
"fmt"
"os"
"os/exec"
"path/filepath"

"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
"golang.org/x/mod/modfile"
)

var (
packages []string

rootCmd = &cobra.Command{
Use: "updater <PACKAGE> <VERSION> [--packages <PACKAGE>,...]]",
Short: "Utility for updating go packages in the oasis-sdk repo",
Version: "0.1.0",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
pkg, version := args[0], args[1]

// Go through all packages and update the dependency (if it exists).
for _, path := range packages {
data, err := os.ReadFile(path)
if err != nil {
cobra.CheckErr(fmt.Errorf("failed to read go.mod file: %w", err))
}
file, err := modfile.ParseLax(path, data, nil)
if err != nil {
cobra.CheckErr(fmt.Errorf("failed to parse go.mod file: %w", err))
}
var requiresPkg bool
for _, req := range file.Require {
if !req.Indirect && req.Mod.Path == pkg {
requiresPkg = true
break
}
}
if !requiresPkg {
// Nothing to do.
continue
}
fmt.Println("Updating", path)

// Update the dependency.
cmd := exec.Command("go", "get", "-u", pkg+"@v"+version)
cmd.Dir = filepath.Dir(path)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
cobra.CheckErr(fmt.Errorf("failed to update dependency: %w", err))
}
// Tidy.
cmd = exec.Command("go", "mod", "tidy")
cmd.Dir = filepath.Dir(path)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
cobra.CheckErr(fmt.Errorf("failed to run go mod tidy: %w", err))
}
}
},
}
)

func main() {
flags := flag.NewFlagSet("", flag.ContinueOnError)
flags.StringSliceVar(&packages, "packages", []string{"./go.mod"}, "go.mod files to update")
rootCmd.Flags().AddFlagSet(flags)

_ = rootCmd.Execute()
}

0 comments on commit 3b9783c

Please sign in to comment.