Skip to content

Commit

Permalink
Automate release through github actions
Browse files Browse the repository at this point in the history
We have to rollback the artifacts management upgrade because of this
issue:
actions/upload-artifact#478

Change-Id: Iae6098239dd9d21430331a6e568a83eeedd80881
  • Loading branch information
tjamet committed Jul 15, 2024
1 parent 4bf10c2 commit 8f01af0
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 49 deletions.
57 changes: 22 additions & 35 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ on:
push:
branches:
- "**"
tags:
- "**"
pull_request:
merge_group:
workflow_call:
inputs:
tag:
description: 'Tag to build'
type: string
required: true

jobs:

Expand Down Expand Up @@ -44,7 +48,14 @@ jobs:
with:
# https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches
# fetch all tags
fetch-depth: 0
fetch-depth: 0

- name: Compute CHANGELOG
id: changed_files
if: ${{ github.event.inputs.tag }}
run: |
sed -i.old "s:## Unreleased:## Unreleased\n\n## ${{ github.event.inputs.tag }} - $(date +%Y-%m-%d):" CHANGELOG.md
rm CHANGELOG.md.old
- name: Map binary name
id: binary
Expand All @@ -69,11 +80,18 @@ jobs:
run: ./${{ steps.binary.outputs.binary_name }} version
if: ${{ !startsWith(matrix.arch, 'arm') }}

- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: ${{ steps.binary.outputs.binary_name }}
path: whalebrew-*

- uses: actions/upload-artifact@v3
if: ${{ matrix.os }} == 'ubuntu-latest' && ${{ matrix.arch }} == 'amd64'
with:
name: CHANGELOG.md
path: CHANGELOG.md
overwrite: true

- name: run tests
run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...

Expand All @@ -87,34 +105,3 @@ jobs:
needs: build
steps:
- run: echo OK

release:
name: release
runs-on: ubuntu-latest
needs: build
if: ${{ startsWith(github.ref, 'refs/tags') }}
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:

- name: Check out code into the Go module directory
uses: actions/checkout@v4
with:
# https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches
# fetch all tags
fetch-depth: 0

- name: Download assets
id: download
uses: actions/download-artifact@v4
with:
path: release/artifacts

- name: Create Release
id: create_release
uses: ./actions/release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
folder: ${{steps.download.outputs.download-path}}
tag_name: ${{ github.ref }}
81 changes: 81 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Release
on:
pull_request:
types: [opened, synchronize, reopened, closed]
workflow_dispatch:
inputs:
tag:
description: 'Tag to build'
required: true
draft:
description: 'This is a draft release'
required: true
type: boolean

jobs:
build:
if: ${{ github.event.inputs.tag }}
uses: ./.github/workflows/go.yml
with:
tag: ${{ github.event.inputs.tag }}

create-release:
needs: build
if: ${{ github.event.inputs.tag }}
name: Create release
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:

- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.WHALEBREW_RELEASE_APP_ID }}
private-key: ${{ secrets.WHALEBREW_RELEASE_SIGNING_KEY }}

- name: Check out code into the Go module directory
uses: actions/checkout@v4
with:
# https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches
# fetch all tags
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}

- name: Download assets
id: download
uses: actions/download-artifact@v3
with:
path: release/artifacts

- name: Commit changelog
run: |
find ${{ steps.download.outputs.download-path }}
cp ${{ steps.download.outputs.download-path }}/CHANGELOG.md/CHANGELOG.md CHANGELOG.md
sed -i.old 's,https://github.com/whalebrew/whalebrew/releases/download/[^/]*/whalebrew,https://github.com/whalebrew/whalebrew/releases/download/${{ github.event.inputs.tag }}/whalebrew,' README.md
rm README.md.old
git config --local user.email "whalebrew@users.noreply.github.com"
git config --local user.name "whalebrew release bot"
git add CHANGELOG.md README.md
git commit -m "Release ${{ github.event.inputs.tag }}"
- name: Push the release branch
if: ${{ github.event.inputs.draft }}
run: |
git push origin HEAD:refs/heads/release/${{ github.event.inputs.tag }}
- name: Create the Release
id: create_release
uses: ./actions/release
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} # This token is provided by Actions, you do not need to create your own token
with:
tag_name: ${{ github.event.inputs.tag }}
target_commitish: ${{ github.event.inputs.draft && format('refs/heads/release/{0}', github.event.inputs.tag) || github.sha }}
folder: ${{ steps.download.outputs.download-path }}
draft: ${{ github.event.inputs.draft }}
pre_release: false
- name: Push updated release
if: ${{ !github.event.inputs.draft }}
run: |
git push origin HEAD:${{ github.ref }}
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN go test -v ./...
RUN go install .

FROM alpine
Expand Down
1 change: 0 additions & 1 deletion actions/release/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ COPY main.go ./
RUN go build -o /bin/release .
COPY main_test.go ./
COPY resources ./resources
RUN go test -v ./...

FROM alpine
COPY --from=build /bin/release /bin/release
Expand Down
10 changes: 8 additions & 2 deletions actions/release/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ inputs:
tag_name:
description: 'The name of the git tag generating the version'
required: true
body:
description: 'The body of the release. This body will be used as a description of the release in the release page'
target_commitish:
description: 'The target commit to release'
draft:
description: 'Whether the realease is a draft'
pre_release:
description: 'Whether the realease is a pre release'
folder:
description: 'The folder containing all the files to recursively upload'
outputs:
Expand All @@ -15,6 +19,8 @@ outputs:
description: 'The URL of the generated release'
release_upload_url:
description: 'The URL where to upload assets'
release_htmlurl:
description: 'The user friendly URL of the generated release'
runs:
using: 'docker'
image: 'Dockerfile'
12 changes: 6 additions & 6 deletions actions/release/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ module github.com/whalebrew/whalebrew/actions/release
go 1.17

require (
github.com/actions-go/toolkit v0.0.0-20220207230919-2c5a93c4f459
github.com/actions-go/toolkit v0.0.0-20231022202615-3973644be7a1
github.com/google/go-github/v42 v42.0.0
github.com/stretchr/testify v1.8.4
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.16.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
14 changes: 14 additions & 0 deletions actions/release/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/actions-go/toolkit v0.0.0-20220207230919-2c5a93c4f459 h1:9xvkwBmqAn4uIEOifdf8c0x/z9WTu5iQ9Wk2eZRVWiU=
github.com/actions-go/toolkit v0.0.0-20220207230919-2c5a93c4f459/go.mod h1:SPTBtjaZ87R+frsWISW1oUaLpRAZsbPzxhMy4Z8jo0A=
github.com/actions-go/toolkit v0.0.0-20220207235722-6bfcbd32f54f h1:zQPhkbGHbaZI6J5Q1bKuAwXgKK5HntaRw4WeUCzwn8Y=
github.com/actions-go/toolkit v0.0.0-20220207235722-6bfcbd32f54f/go.mod h1:SPTBtjaZ87R+frsWISW1oUaLpRAZsbPzxhMy4Z8jo0A=
github.com/actions-go/toolkit v0.0.0-20231022202615-3973644be7a1 h1:/JvooMUYu5gtFKnsvjTanCC5INgxS21AjJflFzL5b74=
github.com/actions-go/toolkit v0.0.0-20231022202615-3973644be7a1/go.mod h1:D5jDCsChxjOG+k+5PGrx0UgXB9U5gCH1ahK/E1q5A/Y=
github.com/bradleyfalzon/ghinstallation/v2 v2.0.3/go.mod h1:tlgi+JWCXnKFx/Y4WtnDbZEINo31N5bcvnCoqieefmk=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
Expand Down Expand Up @@ -81,6 +85,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
Expand Down Expand Up @@ -154,6 +160,8 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down Expand Up @@ -217,13 +225,17 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -405,6 +417,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
52 changes: 48 additions & 4 deletions actions/release/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bufio"
"context"
"crypto/md5"
"crypto/sha1"
Expand Down Expand Up @@ -111,6 +112,30 @@ func uploadAsset(name string, release *github.RepositoryRelease, path string) er
return nil
}

func getReleaseChangeLog(path, tag string) string {
changeLog := ""
fd, err := os.Open(path)
if err != nil {
core.Warningf("failed to open CHANGELOG.md: %v. Won't create release body", err)
} else {
scanner := bufio.NewScanner(fd)
dumpReleaseNotes := false
for scanner.Scan() {
line := scanner.Text()
if dumpReleaseNotes {
if strings.HasPrefix(line, "## ") {
return strings.TrimSpace(changeLog)
}
changeLog += line + "\n"
}
if strings.HasPrefix(line, "## "+tag) {
dumpReleaseNotes = true
}
}
}
return changeLog
}

func main() {
// Create or update release
tag, ok := core.GetInput("tag_name")
Expand All @@ -120,29 +145,45 @@ func main() {
}
}
tag = strings.TrimPrefix(tag, "refs/tags/")

targetCommitish, ok := core.GetInput("target_commitish")
if !ok {
targetCommitish = "master"
}
isDraft, ok := core.GetInput("draft")
if !ok {
isDraft = "true"
}
isPreRelease, ok := core.GetInput("pre_release")
if !ok {
isPreRelease = "true"
}
var err error
var release *github.RepositoryRelease
body := core.GetInputOrDefault("body", "")

releaseName := fmt.Sprintf("%s %s", tag, time.Now().Format("2006-01-02"))

releaseChangeLog := getReleaseChangeLog("CHANGELOG.md", tag)

core.Group("upserting the release", func() {
release, _, err = gha.GitHub.Repositories.GetReleaseByTag(context.Background(), gha.Context.Repo.Owner, gha.Context.Repo.Repo, tag)
if err != nil {
core.Infof("Did not find release to update, creating a new one")
release, _, err = gha.GitHub.Repositories.CreateRelease(context.Background(), gha.Context.Repo.Owner, gha.Context.Repo.Repo, &github.RepositoryRelease{
Name: github.String(releaseName),
TagName: github.String(tag),
TargetCommitish: github.String("master"),
Body: github.String(body),
TargetCommitish: github.String(targetCommitish),
Body: github.String(releaseChangeLog),
Draft: github.Bool(isDraft == "true"),
Prerelease: github.Bool(isPreRelease == "true"),
})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
} else {
core.Infof("Found existing release. Updating it with latest details")
release.Body = github.String(body)
release.Body = github.String(releaseChangeLog)
release.Name = github.String(releaseName)
release, _, err = gha.GitHub.Repositories.EditRelease(context.Background(), gha.Context.Repo.Owner, gha.Context.Repo.Repo, *release.ID, release)
if err != nil {
Expand All @@ -153,6 +194,7 @@ func main() {
core.SetOutput("release_id", fmt.Sprintf("%d", *release.ID))
core.SetOutput("release_url", *release.URL)
core.SetOutput("release_upload_url", *release.UploadURL)
core.SetOutput("release_htmlurl", *release.HTMLURL)
})()

assetsFolder := core.GetInputOrDefault("folder", ".")
Expand Down Expand Up @@ -204,6 +246,8 @@ func main() {
os.Exit(1)
}
}

core.AddStepSummary(fmt.Sprintf("# Release created\n\nTag: %s\nURL: [%s](%s)", tag, *release.HTMLURL, *release.HTMLURL))
}

func init() {
Expand Down
Loading

0 comments on commit 8f01af0

Please sign in to comment.