Skip to content

Commit

Permalink
Release action
Browse files Browse the repository at this point in the history
  • Loading branch information
mdouchement committed Sep 11, 2021
1 parent 9d174c8 commit babe4f3
Show file tree
Hide file tree
Showing 3 changed files with 283 additions and 1 deletion.
241 changes: 241 additions & 0 deletions .github/workflows/release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/fs"
"log"
"net/http"
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
)

type controller struct {
epath string
token string
baseurl string
event event
}

type event struct {
Release struct {
ID int64 `json:"id"`
URL string `json:"url"`
AssetsURL string `json:"assets_url"`
UploadURL string `json:"upload_url"`
TagName string `json:"tag_name"`
TargetCommitish string `json:"target_commitish"`
Name string `json:"name"`
Draft bool `json:"draft"`
Prerelease bool `json:"prerelease"`
} `json:"release"`
}

func main() {
c := &controller{
// https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables
epath: os.Getenv("GITHUB_EVENT_PATH"),
token: os.Getenv("GITHUB_TOKEN"),
baseurl: "https://api.github.com/",
}
fmt.Println("Token size:", len(c.token))

//
//

err := c.load()
if err != nil {
log.Fatal("load: ", err)
}

fmt.Println("RELEASE:", c.event.Release.ID)
fmt.Println("URL:", c.event.Release.URL)
fmt.Println("UPLOAD_URL:", c.event.Release.UploadURL)
fmt.Println("TAG:", c.event.Release.TagName)

//

err = c.update()
if err != nil {
log.Fatal("update: ", err)
}

//

err = c.upload()
if err != nil {
log.Fatal("upload: ", err)
}
}

// https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#release
func (c *controller) load() error {
payload, err := os.ReadFile(c.epath)
if err != nil {
return fmt.Errorf("readfile: %w", err)
}

err = json.Unmarshal(payload, &c.event)
if err != nil {
return fmt.Errorf("parse: %w", err)
}

if !strings.HasPrefix(c.event.Release.URL, c.baseurl) {
return fmt.Errorf("bad url prefix: %s", c.event.Release.URL)
}
if !strings.HasPrefix(c.event.Release.AssetsURL, c.baseurl) {
return fmt.Errorf("bad upload url prefix: %s", c.event.Release.UploadURL)
}

return nil
}

func (c *controller) update() error {
fmt.Println("=> Updating readme")

readme, err := c.readme()
if err != nil {
return fmt.Errorf("readme: %w", err)
}
fmt.Println(readme)

body, err := json.Marshal(map[string]interface{}{
"body": readme,
})

if err != nil {
return fmt.Errorf("body: %w", err)
}

//

req, err := c.request("PATCH", c.event.Release.URL, bytes.NewBuffer(body))
if err != nil {
return fmt.Errorf("request: %w", err)
}

err = c.perform(req, nil)
if err != nil {
return fmt.Errorf("perform: %w", err)
}

return nil
}

func (c *controller) readme() (string, error) {
checksums, err := os.ReadFile("dist/checksum.txt")
if err != nil {
return "", fmt.Errorf("readfile: %w", err)
}

return fmt.Sprintf("```\n%s\n\n%s\n```", runtime.Version(), bytes.TrimSpace(checksums)), nil
}

func (c *controller) upload() error {
baseurl := c.event.Release.UploadURL
if idx := strings.IndexRune(baseurl, '{'); idx > 0 {
baseurl = baseurl[:idx]
}

//

err := filepath.Walk("dist/", func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}

fmt.Println("=> Uploading", path)

//

u, err := url.Parse(baseurl)
if err != nil {
return fmt.Errorf("parse upload url: %w", err)
}
params := u.Query()
params.Set("name", info.Name())
u.RawQuery = params.Encode()

//

f, err := os.Open(path)
if err != nil {
return fmt.Errorf("read file: %w", err)
}
defer f.Close()

//

req, err := c.request("POST", u.String(), f)
if err != nil {
return fmt.Errorf("request: %w", err)
}

req.ContentLength = info.Size()
req.Header.Set("Content-Type", "application/octet-stream")

//

err = c.perform(req, nil)
if err != nil {
return fmt.Errorf("perform: %w", err)
}

return nil
})
if err != nil {
return fmt.Errorf("walk: %w", err)
}

return nil
}

/////////////////////
// //
// HTTP //
// //
/////////////////////

func (c *controller) request(method, url string, body io.Reader) (*http.Request, error) {
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}

req.Header.Set("Accept", "application/vnd.github.v3+json")
if c.token != "" {
req.Header.Set("Authorization", fmt.Sprintf("token %s", c.token))
}

return req, nil
}

func (c *controller) perform(req *http.Request, v interface{}) error {
response, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("do: %w", err)
}
defer response.Body.Close()

if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated {
return fmt.Errorf("status: %s", response.Status)
}

if v != nil {
codec := json.NewDecoder(response.Body)
if err = codec.Decode(v); err != nil {
return fmt.Errorf("decode: %s", response.Status)
}
}

return nil
}
41 changes: 41 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
on:
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows#release
release:
types: [created]
name: Build Release
env:
GO_VERSION: "^1.17.1"
TASK_VERSION: v3.7.3
TASK_SUM: 23e670ab136e25dad74b3c7d97900f7c2879c6874ccaae29e6fc041061be5fb4
jobs:
release:
name: Build binaries
runs-on: ubuntu-latest
steps:
#
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
id: go
#
- name: Tooling(checksum)
run: go install github.com/mdouchement/checksum@master
- name: Tooling(Taskfile)
run: |
curl -LO https://github.com/go-task/task/releases/download/${{ env.TASK_VERSION }}/task_linux_amd64.tar.gz && \
echo "${{ env.TASK_SUM }} task_linux_amd64.tar.gz" | sha256sum -c && \
tar -xf task_linux_amd64.tar.gz && \
cp task /usr/local/bin/
#
- name: Checkout code
uses: actions/checkout@v2
#
- name: Build binaries
run: task build-all
#
- name: Update release
run: go run .github/workflows/release.go
env:
# secrets.GITHUB_TOKEN is created by GH action and is limited to the repository
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
version: '3'

vars:
VERSION: 0.2.0
VERSION: 0.2.1
REVISION: { sh: git rev-parse HEAD }

env:
Expand Down

0 comments on commit babe4f3

Please sign in to comment.