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

Fix truncated checklist issue generation #274

Merged
merged 6 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
28 changes: 14 additions & 14 deletions .github/ISSUE_TEMPLATE/release_template_pre_main.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: Release a new pre-release version of Cilium from the main branch
about: Create a checklist for an upcoming release
title: 'vX.Y.Z-pre.W release'
title: 'vX.Y.Z-pre.N release'
labels: kind/release
assignees: ''

Expand Down Expand Up @@ -30,7 +30,7 @@ assignees: ''
current backporter to merge the outstanding [backport PRs] and stop merging any new
backport PRs until the GitHub issue is closed (to avoid generating incomplete
release notes).
- [ ] Run `./release start --steps 1-pre-check --target-version vX.Y.Z-pre.W`
- [ ] Run `./release start --steps 1-pre-check --target-version vX.Y.Z-pre.N`
- [ ] Check that there are no [release blockers] for the targeted release
version.
- [ ] Ensure that outstanding [backport PRs] are merged (these may be
Expand All @@ -43,7 +43,7 @@ assignees: ''
## Preparation PR (run ~1 day before release date. It can be re-run multiple times.)

- [ ] Go to [release workflow] and Run the workflow from "Branch: main", for
step "2-prepare-release" and version for vX.Y.Z-pre.W
step "2-prepare-release" and version for vX.Y.Z-pre.N
- [ ] Check if the workflow was successful and check the PR opened by the
Release bot.
- [ ] Merge PR
Expand All @@ -54,21 +54,21 @@ assignees: ''
- [ ] FYI, do not wait too much time between a tag is created and the helm charts are published.
Once the tags are published the documentation will be pointing to them. Until we release
the helm chart, users will face issues while trying out our documentation.
- [ ] Run `./release start --steps 3-tag --target-version vX.Y.Z-pre.W`
- [ ] Run `./release start --steps 3-tag --target-version vX.Y.Z-pre.N`
- [ ] Ask a maintainer to approve the build in the following link (keep the URL
of the GitHub run to be used later):
[Cilium Image Release builds](https://github.com/cilium/cilium/actions?query=workflow:%22Image+Release+Build%22)

## Post Tagging (run after docker images are published)

- [ ] Go to [release workflow] and Run the workflow from "Branch: main", for
step "4-post-release" and version for vX.Y.Z-pre.W
step "4-post-release" and version for vX.Y.Z-pre.N
- [ ] Check if the workflow was successful. (There won't be a PR opened
by this step)

## Publish helm (run after docker images are published)

- [ ] Update helm charts `./release start --steps 5-publish-helm --target-version vX.Y.Z-pre.W`
- [ ] Update helm charts `./release start --steps 5-publish-helm --target-version vX.Y.Z-pre.N`
- [ ] Open [Charts Workflow] and check if the workflow run is successful.

## Publish docs (only for pre/rc releases)
Expand Down Expand Up @@ -106,31 +106,31 @@ assignees: ''
```
:confetti_ball: :cilium-radiant: Release Announcement :cilium-radiant::confetti_ball:

Cilium vX.Y.Z-pre.W, vA.B.C, and vD.E.F have been released. Thanks all for your contributions! Please see the release notes below for details :cilium-gopher:
Cilium vX.Y.Z-pre.N, vA.B.C, and vD.E.F have been released. Thanks all for your contributions! Please see the release notes below for details :cilium-gopher:

vX.Y.Z-pre.W: https://github.com/cilium/cilium/releases/tag/vX.Y.Z-pre.W
vX.Y.Z-pre.N: https://github.com/cilium/cilium/releases/tag/vX.Y.Z-pre.N
vA.B.C: https://github.com/cilium/cilium/releases/tag/vA.B.C
vD.E.F: https://github.com/cilium/cilium/releases/tag/vD.E.F
```

### First pre-release

```
:cilium-new: *Cilium vX.Y.Z-pre.W has been released:*
https://github.com/cilium/cilium/releases/tag/vX.Y.Z-pre.W
:cilium-new: *Cilium vX.Y.Z-pre.N has been released:*
https://github.com/cilium/cilium/releases/tag/vX.Y.Z-pre.N

This is the first monthly snapshot for the vX.Y development cycle. There are [vX.Y.Z-pre.W OSS docs](https://docs.cilium.io/en/vX.Y.Z-pre.W) available if you want to pull this version & try it out.
This is the first monthly snapshot for the vX.Y development cycle. There are [vX.Y.Z-pre.N OSS docs](https://docs.cilium.io/en/vX.Y.Z-pre.N) available if you want to pull this version & try it out.
```

### Subsequent pre-/rc- releases

```
*Announcement* :tada: :tada:

:cilium-new: *Cilium vX.Y.Z-pre.W has been released:*
https://github.com/cilium/cilium/releases/tag/vX.Y.Z-pre.W
:cilium-new: *Cilium vX.Y.Z-pre.N has been released:*
https://github.com/cilium/cilium/releases/tag/vX.Y.Z-pre.N

Thank you for the testing and contributing to the previous pre-releases. There are [vX.Y.Z-pre.W OSS docs](https://docs.cilium.io/en/vX.Y.Z-pre.W) available if you want to pull this version & try it out.
Thank you for the testing and contributing to the previous pre-releases. There are [vX.Y.Z-pre.N OSS docs](https://docs.cilium.io/en/vX.Y.Z-pre.N) available if you want to pull this version & try it out.
```

[release workflow]: https://github.com/cilium/cilium/actions/workflows/release.yaml
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/release_template_rc_branch.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ assignees: ''
- Use the settings of the previous stable branch and main as sane defaults
- [ ] On the `vX.Y` branch, prepare for stable release development:
- [ ] Update the VERSION file with the last prerelease for this stable version
- `echo "X.Y.Z-pre.N" > VERSION`
- `echo "X.Y.Z-rc.W" > VERSION`
- [ ] Remove any GitHub workflows from the stable branch that are only
relevant for the main branch.
- Remove workflows that are exclusively triggered by cron job and
Expand Down
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ all: tests release
docker-image:
docker build $(DOCKER_BUILD_FLAGS) -t cilium/release-tool:${IMAGE_TAG} .

.PHONY: generate-golden
generate-golden:
$(MAKE) $(patsubst %.input,%.golden,$(shell find ./testdata/checklist/ -name "*.input"))

%.golden: %.input
$(GO) run ./cmd/ checklist open --dry-run \
--target-version "v1.10.0-pre.0" \
--template $< \
> $@ \

.PHONY: tests
tests:
$(GO) test -mod=vendor ./...
Expand Down
10 changes: 7 additions & 3 deletions cmd/checklist/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,20 @@ func OpenCommand(ctx context.Context, logger *log.Logger) *cobra.Command {
return fmt.Errorf("Failed to validate configuration: %s", err)
}

tmpl, err := prepareChecklist(cfg)
tmpl, err := fetchTemplate(cfg)
if err != nil {
return fmt.Errorf("Failed to fetch template: %w", err)
}
cl, err := prepareChecklist(tmpl, cfg)
if err != nil {
return fmt.Errorf("Failed to apply template configuration to template: %s", err)
}
if cfg.DryRun {
fmt.Printf("%s", tmpl)
fmt.Printf("%s", cl)
return nil
}

return CreateIssue(ctx, ghClient, cfg, tmpl)
return CreateIssue(ctx, ghClient, cfg, cl)
},
}
cmd.Flags().StringVar(&cfg.TemplatePath, "template", "", "Template path to create release checklist")
Expand Down
9 changes: 2 additions & 7 deletions cmd/checklist/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,7 @@ func assembleVersionSubstitutions(version string) ([]string, error) {
return result, nil
}

func prepareChecklist(cfg ChecklistConfig) (string, error) {
tmpl, err := fetchTemplate(cfg)
if err != nil {
return "", fmt.Errorf("Failed to fetch template: %w", err)
}

func prepareChecklist(tmpl []byte, cfg ChecklistConfig) (string, error) {
patterns, err := assembleVersionSubstitutions(cfg.TargetVer)
if err != nil {
return "", fmt.Errorf("Error while parsing version %q: %w", cfg.TargetVer, err)
Expand All @@ -102,7 +97,7 @@ func templateToRequest(tmpl string) (*gh.IssueRequest, error) {
return nil, fmt.Errorf("unable to find metadata, body in issue template, check form of %s", cfg.TemplatePath)
}
meta := segments[1]
body := segments[2]
body := strings.Join(segments[2:], "---")

titleRe := regexp.MustCompile(`title: '(.*)'\n`)
match := titleRe.FindStringSubmatch(meta)
Expand Down
141 changes: 141 additions & 0 deletions cmd/checklist/template_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package checklist

import (
"os"
"path/filepath"
"regexp"
"testing"

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

func Test_assembleVersionSubstitutions(t *testing.T) {
tests := []struct {
name string
err string
input string
want []string
}{
{
name: "Invalid input",
input: "foo",
want: nil,
err: "unexpected version string foo",
},
{
name: "Stable release",
input: "v1.10.0",
want: []string{
"X.Y.Z-rc.W", "",
"X.Y.Z-pre.N", "",
"X.Y.Z", "1.10.0",
"X.Y.W", "1.10.1",
"X.Y-1", "1.9",
"X.Y+1", "1.11",
"X.Y", "1.10",
},
},
{
name: "Release candidate",
input: "v1.10.0-rc.0",
want: []string{
"X.Y.Z-rc.W", "1.10.0-rc.0",
"X.Y.Z-pre.N", "1.10.0-rc.0",
"X.Y.Z", "1.10.0",
"X.Y.W", "1.10.1",
"X.Y-1", "1.9",
"X.Y+1", "1.11",
"X.Y", "1.10",
},
},
{
name: "Prerelease",
input: "v1.10.0-pre.0",
want: []string{
"X.Y.Z-rc.W", "1.10.0-pre.0",
"X.Y.Z-pre.N", "1.10.0-pre.0",
"X.Y.Z", "1.10.0",
"X.Y.W", "1.10.1",
"X.Y-1", "1.9",
"X.Y+1", "1.11",
"X.Y", "1.10",
},
},
}

for _, tt := range tests {
sub, err := assembleVersionSubstitutions(tt.input)
if tt.err != "" {
assert.ErrorContains(t, err, tt.err, tt.name+" encountered unexpected error")
}
assert.Equal(t, sub, tt.want, tt.name+" generated unexpected substitutions")
}
}

func Test_prepareChecklist(t *testing.T) {
cfg := ChecklistConfig{
TargetVer: "v1.10.0-pre.0",
}
testdataPath := filepath.Join("..", "..", "testdata", "checklist")

paths, err := filepath.Glob(filepath.Join(testdataPath, "*.input"))
if err != nil {
t.Fatal(err)
}

for _, path := range paths {
_, filename := filepath.Split(path)
testname := filename[:len(filename)-len(filepath.Ext(path))]

t.Run(testname, func(t *testing.T) {
source, err := os.ReadFile(path)
assert.Nil(t, err, "failed to read input template: ", err)

output, err := prepareChecklist(source, cfg)
assert.Nil(t, err, "failed to render checklist: ", err)

golden := filepath.Join(testdataPath, testname+".golden")
want, err := os.ReadFile(golden)
assert.Nil(t, err, "error reading golden output: ", err)

assert.Equal(t, output, string(want), "template processing did not match golden output. Check for bugs or run 'make generate-golden' to update the golden tests.")
})
}
}

func Test_templateToRequest(t *testing.T) {
cfg := ChecklistConfig{
TargetVer: "v1.10.0-pre.0",
}
testdataPath := filepath.Join("..", "..", "testdata", "checklist")

paths, err := filepath.Glob(filepath.Join(testdataPath, "*.input"))
if err != nil {
t.Fatal(err)
}

for _, path := range paths {
_, filename := filepath.Split(path)
testname := filename[:len(filename)-len(filepath.Ext(path))]

t.Run(testname, func(t *testing.T) {
source, err := os.ReadFile(path)
assert.Nil(t, err, "failed to read input template: ", err)

barRe := regexp.MustCompile(`---`)
expBarCount := len(barRe.FindAll(source, -1)) - 2 // Exclude the metadata section at the top

cl, err := prepareChecklist(source, cfg)
assert.Nil(t, err, "failed to render checklist: ", err)

req, err := templateToRequest(cl)
assert.Nil(t, err, "failed to translate checklist into GitHub request: ", err)

barCount2 := barRe.FindAllString(*req.Body, -1)
assert.Equal(t, len(barCount2), expBarCount, "template unexpectedly removed valid horizontal separators")
})
}
}
Loading