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 ...@@ -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) - [ ] 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 - [ ] add all required fixes to make `master` Pipeline passing
- [ ] `git checkout master && git pull` in your local working copy! - [ ] `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 - [ ] add **v{{.Major}}.{{.Minor}}.0-rc1** CHANGELOG entries and commit
```bash ```bash
...@@ -92,9 +104,25 @@ this day, will be released with next release. ...@@ -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 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. 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) - [ ] 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 - [ ] add all required fixes to make `{{.Major}}-{{.Minor}}-stable` Pipeline passing
- [ ] `git checkout {{.Major}}-{{.Minor}}-stable && git pull` in your local working copy! - [ ] `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 - [ ] add **v{{.Major}}.{{.Minor}}.0-rcZ** CHANGELOG entries and commit
```bash ```bash
...@@ -113,39 +141,53 @@ if the only RC version was the _RC1_ released near 7th day of month. ...@@ -113,39 +141,53 @@ if the only RC version was the _RC1_ released near 7th day of month.
## At 22th - the release day ## At 22th - the release day
- [ ] Before 12:00 UTC #### 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 - [ ] 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 ```bash
git add CHANGELOG.md && git commit -m "Update CHANGELOG for v{{.Major}}.{{.Minor}}.0" -S 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 - [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to latest production version: [link to MR]
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`: #### Before 15:00 UTC
```bash - [ ] 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)
git checkout master; git merge --no-ff {{.Major}}-{{.Minor}}-stable - [ ] add all required fixes to make `v{{.Major}}.{{.Minor}}.0` passing
# check that the only changes are in CHANGELOG.md - [ ] deploy stable version to all production Runners
git push
```
- [ ] Before 15:00 UTC #### After helm chart MR is merged
- [ ] 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 ([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 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 important changes merged into stable branch (like bug/security fixes) the RC should be
...@@ -161,6 +203,18 @@ template: ...@@ -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) - [ ] 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 - [ ] add all required fixes to make `{{.Major}}-{{.Minor}}-stable` Pipeline passing
- [ ] `git checkout {{.Major}}-{{.Minor}}-stable && git pull` in your local working copy! - [ ] `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 - [ ] add **v{{.Major}}.{{.Minor}}.0-rcZ** CHANGELOG entries and commit
```bash ```bash
......
...@@ -366,13 +366,9 @@ prepare_release_checklist_issue_dry_run: ...@@ -366,13 +366,9 @@ prepare_release_checklist_issue_dry_run:
make prepare_release_checklist_issue opts="-dry-run" make prepare_release_checklist_issue opts="-dry-run"
prepare_release_checklist_issue: opts ?= "" 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: prepare_release_checklist_issue:
@go run ./scripts/prepare_release_checklist_issue.go \ @go run ./scripts/prepare_release_checklist_issue.go \
-issue-template-file ".gitlab/issue_templates/Release Checklist.md" \ -issue-template-file ".gitlab/issue_templates/Release Checklist.md" \
-major $(major) \
-minor $(minor) \
$(opts) $(opts)
development_setup: development_setup:
......
...@@ -10,9 +10,11 @@ import ( ...@@ -10,9 +10,11 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"regexp"
"strconv" "strconv"
"strings" "strings"
"text/template" "text/template"
"time"
) )
type ReleaseMetadata struct { type ReleaseMetadata struct {
...@@ -23,23 +25,202 @@ type ReleaseMetadata struct { ...@@ -23,23 +25,202 @@ type ReleaseMetadata struct {
ReleaseBlogPostDeadline string 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 ReleasePostLabel = "release post"
var releaseMetadata ReleaseMetadata
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") LayoutDay = "2006-01-02"
var noInteractive = flag.Bool("no-interactive", false, "Don't ask, just try to work!") )
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") type listMergeRequestsResponse []listMergeRequestsResponseEntry
var minor = flag.String("minor", "", "Minor version number")
var releaseManagerHandle = flag.String("release-manager-handle", "", "GitLab.com handle of the release manager") type listMergeRequestsResponseEntry struct {
var releaseBlogPostMR = flag.String("release-blog-post-mr", "", "ID of the Release Blog Post MR") ID int `json:"iid"`
var releaseBlogPostDeadline = flag.String("release-blog-post-deadline", "", "Deadline for adding Runner specific content to the Release Blog Post") 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() { func main() {
fmt.Println()
fmt.Println("\nGitLab Runner release checklist issue generator")
fmt.Println()
flag.Usage = func() { flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
fmt.Fprintf(os.Stderr, "\n %s [OPTIONS]\n\nOptions:\n", os.Args[0]) fmt.Fprintf(os.Stderr, "\n %s [OPTIONS]\n\nOptions:\n", os.Args[0])
...@@ -170,7 +351,7 @@ type createIssueResponse struct { ...@@ -170,7 +351,7 @@ type createIssueResponse struct {
} }
func postIssue(title, content string) { 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{ options := &createIssueOptions{
Title: title, 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