Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci(helm): auto public Helm chart after PR merged #7526

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/bypass-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ on:
- 'mkdocs.yml'
- 'LICENSE'
- '.release-please-manifest.json'
- 'helm/trivy/Chart.yaml'
pull_request:
paths:
- '**.md'
- 'docs/**'
- 'mkdocs.yml'
- 'LICENSE'
- '.release-please-manifest.json'
- 'helm/trivy/Chart.yaml'
jobs:
test:
name: Test
Expand Down
37 changes: 36 additions & 1 deletion .github/workflows/publish-chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ name: Publish Helm chart
on:
workflow_dispatch:
pull_request:
types:
- opened
- synchronize
- reopened
- closed
afdesk marked this conversation as resolved.
Show resolved Hide resolved
branches:
- main
paths:
Expand All @@ -18,7 +23,9 @@ env:
KIND_VERSION: "v0.14.0"
KIND_IMAGE: "kindest/node:v1.23.6@sha256:b1fa224cc6c7ff32455e0b1fd9cbfd3d3bc87ecaa8fcb06961ed1afb3db0f9ae"
jobs:
# `test-chart` job starts if a PR with Helm Chart is created, merged etc.
test-chart:
if: github.event_name != 'push'
runs-on: ubuntu-20.04
steps:
- name: Checkout
Expand Down Expand Up @@ -48,8 +55,36 @@ jobs:
sed -i -e '136s,false,'true',g' ./helm/trivy/values.yaml
ct lint-and-install --validate-maintainers=false --charts helm/trivy

# `update-chart-version` job starts if a new tag is pushed
update-chart-version:
if: github.event_name == 'push'
afdesk marked this conversation as resolved.
Show resolved Hide resolved
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- name: Set up Git user
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"

- name: Install tools
uses: aquaproj/aqua-installer@v3.0.1
with:
aqua_version: v1.25.0
aqua_opts: ""

- name: Create a PR with Trivy version
run: mage helm:updateVersion
env:
# Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
# This allows the created PR to trigger tests and other workflows
GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}

# `publish-chart` job starts if a PR with a new Helm Chart is merged or manually
publish-chart:
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be wrong, but I remember that the events for merging a PR by default and merging using merge queue may be different.
Does this work correctly?

needs:
- test-chart
runs-on: ubuntu-20.04
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- 'mkdocs.yml'
- 'LICENSE'
- '.release-please-manifest.json' ## don't run tests for release-please PRs
- 'helm/trivy/Chart.yaml'
merge_group:
env:
GO_VERSION: '1.22'
Expand Down
110 changes: 110 additions & 0 deletions magefiles/helm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//go:build mage_helm

package main

import (
"fmt"
"log"
"os"
"strconv"
"strings"

"github.com/magefile/mage/sh"
"golang.org/x/xerrors"
"gopkg.in/yaml.v3"
)

const chartFile = "./helm/trivy/Chart.yaml"

func main() {
trivyVersion, err := version()
if err != nil {
log.Fatalf("could not determine Trivy version: %v", err)
}
input, err := os.ReadFile(chartFile)
if err != nil {
log.Fatalf("could not find helm chart %s: %v", chartFile, err)
}
jsonData := map[string]interface{}{}
DmitriyLewen marked this conversation as resolved.
Show resolved Hide resolved
if err := yaml.Unmarshal(input, &jsonData); err != nil {
log.Fatalf("could not unmarshal helm chart %s: %v", chartFile, err)
}
currentAppVersion, ok := jsonData["appVersion"].(string)
if !ok {
log.Fatalf("could not determine current app version")
}
currentHelmVersion, ok := jsonData["version"].(string)
if !ok {
log.Fatalf("could not determine current helm version")
}
newHelmVersion := newHelmVersion(currentHelmVersion, currentAppVersion, trivyVersion)

log.Printf("Current helm version %q with Trivy %q will bump up %q with Trivy %q",
currentHelmVersion, currentAppVersion, newHelmVersion, trivyVersion)

newBranch := fmt.Sprintf("ci/helm-chart/bump-trivy-to-%s", trivyVersion)
title := fmt.Sprintf("ci(helm): bump Trivy version to %s", trivyVersion)
description := fmt.Sprintf("This PR bumps Trivy up to the %s version for the Helm chart.", trivyVersion)
DmitriyLewen marked this conversation as resolved.
Show resolved Hide resolved

cmds := [][]string{
[]string{"sed", "-i", "-e", fmt.Sprintf("s/appVersion: %s/appVersion: %s/g", currentAppVersion, trivyVersion), chartFile},
[]string{"sed", "-i", "-e", fmt.Sprintf("s/version: %s/version: %s/g", currentHelmVersion, trivyVersion), chartFile},
DmitriyLewen marked this conversation as resolved.
Show resolved Hide resolved
[]string{"git", "switch", "-c", newBranch},
[]string{"git", "add", "./helm/trivy/Chart.yaml"},
[]string{"git", "commit", "-m", title},
[]string{"git", "push", "origin", newBranch},
[]string{"gh", "pr", "create", "--base", "main", "--head", newBranch, "--title", title, "--body", description, "--repo", "$GITHUB_REPOSITORY"},
}

if err := runShCommands(cmds); err != nil {
log.Fatal(err)
}
log.Print("Successfully created PR with a new helm version")
}

func runShCommands(cmds [][]string) error {
for _, cmd := range cmds {
if err := sh.Run(cmd[0], cmd[1:]...); err != nil {
return xerrors.Errorf("failed to run %v: %w", cmd, err)
}
}
return nil
}

func splitVersion(version string) []int {
items := strings.Split(version, ".")
result := make([]int, len(items))
for i, item := range items {
result[i], _ = strconv.Atoi(item)
}
return result
}

func newHelmVersion(currentHelm, currentTrivy, newTrivy string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 1e4b16c

ch := splitVersion(currentHelm)
ct := splitVersion(currentTrivy)
tr := splitVersion(newTrivy)

if len(ch) != len(ct) || len(ch) != len(tr) || len(ch) != 3 {
log.Fatalf("invalid version lengths for %q, %q and %q", currentHelm, currentTrivy, newTrivy)
}

n := len(ch)
res := make([]string, n)
if tr[0] != ct[0] {
res[0] = strconv.Itoa(tr[0])
res[1] = strconv.Itoa(tr[1])
res[2] = "0"
return strings.Join(res, ".")
}

res[0] = strconv.Itoa(tr[0])
if tr[1] != ct[1] {
res[1] = strconv.Itoa(ch[1] + tr[1] - ct[1])
res[2] = "0"
} else {
res[1] = strconv.Itoa(ch[1])
res[2] = strconv.Itoa(ch[2] + tr[2] - ct[2])
}
return strings.Join(res, ".")
}
61 changes: 61 additions & 0 deletions magefiles/helm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//go:build mage_helm

package main

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestNewVersion(t *testing.T) {
tests := []struct {
name string
currentHelmVersion string
currentTrivyVersion string
newTrivyVersion string
newHelmVersion string
}{
{
"created the first patch",
"0.1.0",
"0.55.0",
"0.55.1",
"0.1.1",
},
{
"created the second patch",
"0.1.1",
"0.55.1",
"0.55.2",
"0.1.2",
},
{
"created the second patch but helm chart was changed",
"0.1.2",
"0.55.1",
"0.55.2",
"0.1.3",
},
{
"created a new minor version",
"0.1.1",
"0.55.1",
"0.56.0",
"0.2.0",
},
{
"created a new major version",
"0.1.1",
"0.55.1",
"1.0.0",
"1.0.0",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, test.newHelmVersion, newHelmVersion(test.currentHelmVersion, test.currentTrivyVersion, test.newTrivyVersion))
})
}
}
7 changes: 7 additions & 0 deletions magefiles/magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,10 @@ func (CloudActions) Generate() error {
func VEX(_ context.Context, dir string) error {
return sh.RunWith(ENV, "go", "run", "-tags=mage_vex", "./magefiles/vex.go", "--dir", dir)
}

type Helm mg.Namespace

// UpdateVersion updates a version for Trivy Helm Chart and creates a PR
func (Helm) UpdateVersion() error {
return sh.RunWith(ENV, "go", "run", "-tags=mage_helm", "./magefiles")
}