Commit 14e479f8 authored by Steve Azzopardi's avatar Steve Azzopardi 🌃

Merge branch 'docs-update-release-checklist-and-generator' into 'master'

Docs update release checklist and generator

See merge request gitlab-org/gitlab-runner!1073
parents b7e640d9 816284e8
......@@ -33,6 +33,18 @@ https://gitlab.com/gitlab-org/gitlab-runner/blob/master/docs/release_process/how
- [ ] check if Pipeline for `master` is passing: [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/master/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/master)
- [ ] add all required fixes to make `master` Pipeline passing
- [ ] `git checkout master && git pull` in your local working copy!
- [ ] prepare CHANGELOG entries
```bash
./scripts/prepare-changelog-entries.rb
```
Copy the lines to the beginning of `CHANGELOG.md` file and add a proper header:
```markdown
v{{.Major}}.{{.Minor}}.0-rc1 (TODAY_DATE_HERE)
```
- [ ] add **v{{.Major}}.{{.Minor}}.0-rc1** CHANGELOG entries and commit
```bash
......@@ -92,9 +104,25 @@ this day, will be released with next release.
At this day we should release an RC version, if there was no RC recently - especially
if the only RC version was the _RC1_ released near 7th day of month.
> **Notice:** If there was no new commits picked into `{{.Major}}-{{.Minor}}-stable` branch since
previous RC, we can skip this step. There is no need in releasing and deploying an RC identical
to the one that already exists.
- [ ] check if Pipeline for `{{.Major}}-{{.Minor}}-stable` is passing: [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/{{.Major}}-{{.Minor}}-stable/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/{{.Major}}-{{.Minor}}-stable)
- [ ] add all required fixes to make `{{.Major}}-{{.Minor}}-stable` Pipeline passing
- [ ] `git checkout {{.Major}}-{{.Minor}}-stable && git pull` in your local working copy!
- [ ] prepare CHANGELOG entries
```bash
./scripts/prepare-changelog-entries.rb
```
Copy the lines to the beginning of `CHANGELOG.md` file and add a proper header:
```markdown
v{{.Major}}.{{.Minor}}.0-rcZ (TODAY_DATE_HERE)
```
- [ ] add **v{{.Major}}.{{.Minor}}.0-rcZ** CHANGELOG entries and commit
```bash
......@@ -113,39 +141,53 @@ if the only RC version was the _RC1_ released near 7th day of month.
## At 22th - the release day
- [ ] Before 12:00 UTC
- [ ] `git checkout {{.Major}}-{{.Minor}}-stable && git pull` in your local working copy!
- [ ] merge all RCx CHANGELOG entries into release entry and commit
#### Before 12:00 UTC
- [ ] check if Pipeline for `{{.Major}}-{{.Minor}}-stable` is passing: [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/{{.Major}}-{{.Minor}}-stable/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/{{.Major}}-{{.Minor}}-stable)
- [ ] add all required fixes to make `{{.Major}}-{{.Minor}}-stable` Pipeline passing
- [ ] `git checkout {{.Major}}-{{.Minor}}-stable && git pull` in your local working copy!
- [ ] merge all RCx CHANGELOG entries into release entry
Put a proper header at the begining:
```markdown
v{{.Major}}.{{.Minor}}.0 (TODAY_DATE_HERE)
```
- [ ] add **v{{.Major}}.{{.Minor}}.0** CHANGELOG entries and commit
```bash
git add CHANGELOG.md && git commit -m "Update CHANGELOG for v{{.Major}}.{{.Minor}}.0" -S
```
- [ ] tag and push **v{{.Major}}.{{.Minor}}.0** and **{{.Major}}-{{.Minor}}-stable**:
- [ ] tag and push **v{{.Major}}.{{.Minor}}.0** and **{{.Major}}-{{.Minor}}-stable**:
```bash
git tag -s v{{.Major}}.{{.Minor}}.0 -m "Version v{{.Major}}.{{.Minor}}.0" && git push origin {{.Major}}-{{.Minor}}-stable v{{.Major}}.{{.Minor}}.0
```
- [ ] checkout to `master` and merge `{{.Major}}-{{.Minor}}-stable` into `master` (only this one time, to update CHANGELOG.md and make the tag available for ./scripts/prepare-changelog-entries.rb in next stable release), push `master`:
```bash
git checkout master; git merge --no-ff {{.Major}}-{{.Minor}}-stable
# check that the only changes are in CHANGELOG.md
git push
```
```bash
git tag -s v{{.Major}}.{{.Minor}}.0 -m "Version v{{.Major}}.{{.Minor}}.0" && git push origin {{.Major}}-{{.Minor}}-stable v{{.Major}}.{{.Minor}}.0
```
- [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to latest production version: [link to MR]
- [ ] checkout to `master` and merge `{{.Major}}-{{.Minor}}-stable` into `master` (only this one time, to update CHANGELOG.md and make the tag available for ./scripts/prepare-changelog-entries.rb in next stable release), push `master`:
#### Before 15:00 UTC
```bash
git checkout master; git merge --no-ff {{.Major}}-{{.Minor}}-stable
# check that the only changes are in CHANGELOG.md
git push
```
- [ ] wait for Pipeline for `v{{.Major}}.{{.Minor}}.0` to pass [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/v{{.Major}}.{{.Minor}}.0/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/v{{.Major}}.{{.Minor}}.0)
- [ ] add all required fixes to make `v{{.Major}}.{{.Minor}}.0` passing
- [ ] deploy stable version to all production Runners
- [ ] Before 15:00 UTC
- [ ] wait for Pipeline for `v{{.Major}}.{{.Minor}}.0` to pass [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/v{{.Major}}.{{.Minor}}.0/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/v{{.Major}}.{{.Minor}}.0)
- [ ] add all required fixes to make `v{{.Major}}.{{.Minor}}.0` passing
- [ ] deploy stable version to all production Runners
- [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to latest production version: [link to MR]
#### After helm chart MR is merged
- [ ] After helm chart MR is merged ([link to MR]):
- [ ] update Runner's chart version [used by GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/models/clusters/applications/runner.rb): [link to MR]
- [ ] update Runner's chart version [used by GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/models/clusters/applications/runner.rb): [link to MR]
**RC release template**
## RC release template
There should be at least one RC version between RC1 and stable release. If there are any
important changes merged into stable branch (like bug/security fixes) the RC should be
......@@ -161,6 +203,18 @@ template:
- [ ] check if Pipeline for `{{.Major}}-{{.Minor}}-stable` is passing: [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/{{.Major}}-{{.Minor}}-stable/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/{{.Major}}-{{.Minor}}-stable)
- [ ] add all required fixes to make `{{.Major}}-{{.Minor}}-stable` Pipeline passing
- [ ] `git checkout {{.Major}}-{{.Minor}}-stable && git pull` in your local working copy!
- [ ] prepare CHANGELOG entries
```bash
./scripts/prepare-changelog-entries.rb
```
Copy the lines to the beginning of `CHANGELOG.md` file and add a proper header:
```markdown
v{{.Major}}.{{.Minor}}.0-rcZ (TODAY_DATE_HERE)
```
- [ ] add **v{{.Major}}.{{.Minor}}.0-rcZ** CHANGELOG entries and commit
```bash
......
......@@ -366,13 +366,9 @@ prepare_release_checklist_issue_dry_run:
make prepare_release_checklist_issue opts="-dry-run"
prepare_release_checklist_issue: opts ?= ""
prepare_release_checklist_issue: major := $(shell cat VERSION | awk -F'.' '{print $$1}')
prepare_release_checklist_issue: minor := $(shell cat VERSION | awk -F'.' '{print $$2}')
prepare_release_checklist_issue:
@go run ./scripts/prepare_release_checklist_issue.go \
-issue-template-file ".gitlab/issue_templates/Release Checklist.md" \
-major $(major) \
-minor $(minor) \
$(opts)
development_setup:
......
......@@ -10,9 +10,11 @@ import (
"net/http"
"net/url"
"os"
"regexp"
"strconv"
"strings"
"text/template"
"time"
)
type ReleaseMetadata struct {
......@@ -23,23 +25,202 @@ type ReleaseMetadata struct {
ReleaseBlogPostDeadline string
}
const GITLAB_RUNNER_PROJECT_ID = "gitlab-org/gitlab-runner"
const (
GitLabRunnerProjectID = "gitlab-org/gitlab-runner"
WWWGitlabComProjectID = "gitlab-com/www-gitlab-com"
var reader *bufio.Reader
var releaseMetadata ReleaseMetadata
ReleasePostLabel = "release post"
var templateFilePath = flag.String("issue-template-file", ".gitlab/issue_templates/Release Checklist.md", "Path to a file with issue template")
ReleaseManagerHandleEnvVariable = "GITLAB_RUNNER_RELEASE_MANAGER_HANDLE"
VersionFile = "./VERSION"
var dryRun = flag.Bool("dry-run", false, "Show issue content instead of creating it in GitLab")
var noInteractive = flag.Bool("no-interactive", false, "Don't ask, just try to work!")
LayoutDay = "2006-01-02"
)
var (
reader *bufio.Reader
releaseMetadata ReleaseMetadata
defaultVersion []string
defaultMergeRequest []string
templateFilePath = flag.String("issue-template-file", ".gitlab/issue_templates/Release Checklist.md", "Path to a file with issue template")
dryRun = flag.Bool("dry-run", false, "Show issue content instead of creating it in GitLab")
noInteractive = flag.Bool("no-interactive", false, "Don't ask, just try to work!")
major = flag.String("major", detectVersion()[0], "Major version number")
minor = flag.String("minor", detectVersion()[1], "Minor version number")
releaseManagerHandle = flag.String("release-manager-handle", defaultReleaseManagerHandle(), "GitLab.com handle of the release manager")
releaseBlogPostMR = flag.String("release-blog-post-mr", detectBlogPostMergeRequest()[0], "ID of the Release Blog Post MR")
releaseBlogPostDeadline = flag.String("release-blog-post-deadline", detectReleaseMergeRequestDeadline(), "Deadline for adding Runner specific content to the Release Blog Post")
)
func detectVersion() []string {
if len(defaultVersion) > 0 {
return defaultVersion
}
fmt.Println("Auto-detecting version...")
content, err := ioutil.ReadFile(VersionFile)
if err != nil {
fmt.Printf("Error while reading version file %q: %v", VersionFile, err)
return []string{"", ""}
}
fmt.Printf("Found: %s\n", content)
defaultVersion = strings.Split(string(content), ".")
return defaultVersion
}
func defaultReleaseManagerHandle() string {
fmt.Println("Auto-detecting Release Manager handle...")
handle := os.Getenv(ReleaseManagerHandleEnvVariable)
fmt.Printf("Found: %s\n", handle)
return handle
}
var major = flag.String("major", "", "Major version number")
var minor = flag.String("minor", "", "Minor version number")
var releaseManagerHandle = flag.String("release-manager-handle", "", "GitLab.com handle of the release manager")
var releaseBlogPostMR = flag.String("release-blog-post-mr", "", "ID of the Release Blog Post MR")
var releaseBlogPostDeadline = flag.String("release-blog-post-deadline", "", "Deadline for adding Runner specific content to the Release Blog Post")
type listMergeRequestsResponse []listMergeRequestsResponseEntry
type listMergeRequestsResponseEntry struct {
ID int `json:"iid"`
WebURL string `json:"web_url"`
Title string `json:"title"`
Description string `json:"description"`
}
func detectBlogPostMergeRequest() []string {
if len(defaultMergeRequest) > 0 {
return defaultMergeRequest
}
fmt.Println("Auto-detecting Release Post merge request...")
version := detectVersion()
q := url.Values{}
q.Add("labels", ReleasePostLabel)
q.Add("state", "opened")
q.Add("milestone", fmt.Sprintf("%s.%s", version[0], version[1]))
rawURL := fmt.Sprintf("https://gitlab.com/api/v4/projects/%s/merge_requests?%s", url.QueryEscape(WWWGitlabComProjectID), q.Encode())
findMergeRequestURL, err := url.Parse(rawURL)
if err != nil {
fmt.Printf("Error while parsing findMergeRequestURL: %v", err)
return []string{"", ""}
}
req, err := http.NewRequest(http.MethodGet, findMergeRequestURL.String(), nil)
if err != nil {
fmt.Printf("Error while creating HTTP Request: %v", err)
return []string{"", ""}
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Printf("Error while requesting API endpoint: %v", err)
return []string{"", ""}
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("Error while reading response body: %v", err)
return []string{"", ""}
}
var response listMergeRequestsResponse
err = json.Unmarshal(body, &response)
if err != nil {
fmt.Printf("Error while parsing response JSON: %v", err)
return []string{"", ""}
}
printEntry := func(entry listMergeRequestsResponseEntry) {
fmt.Printf("\t%-40q %s\n", entry.Title, entry.WebURL)
}
fmt.Println("Found following www-gitlab-com merge requests:")
for _, entry := range response {
printEntry(entry)
}
if len(response) < 1 {
fmt.Println("Release Post merge request was not auto-detected. Please enter the ID manually")
return []string{"", ""}
}
chosen := response[0]
fmt.Println("Choosing:")
printEntry(chosen)
r := regexp.MustCompile("gitlab.com/gitlab-com/www-gitlab-com/blob/release-\\d+-\\d+/data/release_posts/(\\d+)_(\\d+)_(\\d+)_gitlab_\\d+_\\d+_released.yml")
dateParts := r.FindStringSubmatch(chosen.Description)
defaultMergeRequest = []string{
strconv.Itoa(chosen.ID),
fmt.Sprintf("%s-%s-%s", dateParts[1], dateParts[2], dateParts[3]),
}
return defaultMergeRequest
}
func detectReleaseMergeRequestDeadline() string {
fmt.Println("Auto-detecting Release Post entry deadline...")
offsetMap := map[time.Weekday]int{
time.Monday: -11,
time.Tuesday: -11,
time.Wednesday: -9,
time.Thursday: -9,
time.Friday: -9,
time.Saturday: -9,
time.Sunday: -10,
}
date := detectBlogPostMergeRequest()[1]
if len(date) < 1 {
fmt.Println("Could not detect the date of Release...")
return ""
}
releaseDate, err := time.Parse(LayoutDay, date)
if err != nil {
fmt.Printf("Could not parse detected date %q: %v", date, err)
return ""
}
offset := offsetMap[releaseDate.Weekday()]
deadlineTime := releaseDate.Add(time.Duration(24*offset) * time.Hour)
deadline := deadlineTime.Format(LayoutDay)
fmt.Printf("Decided to use %q. Please adjust if required!\n", deadline)
return deadline
}
func main() {
fmt.Println()
fmt.Println("\nGitLab Runner release checklist issue generator")
fmt.Println()
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
fmt.Fprintf(os.Stderr, "\n %s [OPTIONS]\n\nOptions:\n", os.Args[0])
......@@ -170,7 +351,7 @@ type createIssueResponse struct {
}
func postIssue(title, content string) {
newIssueURL := fmt.Sprintf("https://gitlab.com/api/v4/projects/%s/issues", url.QueryEscape(GITLAB_RUNNER_PROJECT_ID))
newIssueURL := fmt.Sprintf("https://gitlab.com/api/v4/projects/%s/issues", url.QueryEscape(GitLabRunnerProjectID))
options := &createIssueOptions{
Title: title,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment