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

ci: auto update generated files #78

Merged
merged 7 commits into from
Jan 29, 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
40 changes: 40 additions & 0 deletions .github/workflows/gen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: "Auto generate sources"

on:
schedule:
- cron: '42 14 * * *'
workflow_dispatch:

jobs:
autogen:
name: Auto generate sources
runs-on: 'ubuntu-latest'
permissions:
contents: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5

- name: Generate
run: |
go generate ./...
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Commit changes if any
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
# If there are changes to the generated files, commit them
if [[ -n $(git status --porcelain) ]]; then
git add .
git commit -m "chore: update generated files" -m "[skip ci]"
git push
else
echo "::notice::Generated files are up to date."
fi

123 changes: 99 additions & 24 deletions gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ package main

import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"go/format"
"io"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -97,6 +99,21 @@ var goversions = map[string]*GoVersion{
}
`))

var client = &http.Client{}

var authRequest func(*http.Request)

func init() {
token := os.Getenv("GITHUB_TOKEN")
if token != "" {
authRequest = func(r *http.Request) {
r.Header.Set("Authorization", "Bearer "+token)
}
} else {
authRequest = func(r *http.Request) {}
}
}

type ghResp struct {
Sha string `json:"sha"`
Url string `json:"url"`
Expand Down Expand Up @@ -154,8 +171,59 @@ type goversion struct {
Date string
}

// diffCode returns false if a and b have different other than the date.
func diffCode(a, b string) bool {
if a == b {
return false
}

aLines := strings.Split(a, "\n")
bLines := strings.Split(b, "\n")

// ignore the license and the date
aLines = aLines[21:]
bLines = bLines[21:]

if len(aLines) != len(bLines) {
return true
}

for i := 0; i < len(aLines); i++ {
if aLines[i] != bLines[i] {
return true
}
}

return false
}

func writeOnDemand(new []byte, target string) {
old, err := os.ReadFile(target)
if err != nil {
fmt.Println("Error when reading the old file:", target, err)
return
}

old, _ = format.Source(old)
new, _ = format.Source(new)

// Compare the old and the new.
if !diffCode(string(old), string(new)) {
fmt.Println(target + " no changes.")
return
}

fmt.Println(target + " changes detected.")

// Write the new file.
err = os.WriteFile(target, new, 0664)
if err != nil {
fmt.Println("Error when writing the new file:", err)
return
}
}

func processGoVersions() {
client := http.DefaultClient
tags := make([]*tagResp, 0)

// Fetch all tags
Expand All @@ -165,15 +233,17 @@ func processGoVersions() {
requestURL = &tagsRequestURL
for *requestURL != "" {
fmt.Println("Fetching latests tags")
resp, err := client.Get(tagsRequestURL)
req, _ := http.NewRequest(http.MethodGet, *requestURL, nil)
authRequest(req)
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error when fetching tags:", err.Error())
resp.Body.Close()
continue
}
next := getNextPageURL(resp)
*requestURL = next
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
fmt.Println("Error when ready response body:", err)
Expand All @@ -182,7 +252,7 @@ func processGoVersions() {
var newTags []*tagResp
err = json.Unmarshal(body, &newTags)
if err != nil {
fmt.Println("Error when parsing the json:", err)
fmt.Println("Error when parsing the json:", string(body), err)
continue
}
tags = append(tags, newTags...)
Expand Down Expand Up @@ -217,13 +287,15 @@ func processGoVersions() {
continue
}

resp, err := client.Get(fmt.Sprintf(commitRequestURLFormatStr, tag.Commit.Sha))
req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf(commitRequestURLFormatStr, tag.Commit.Sha), nil)
authRequest(req)
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error when fetching commit info:", err)
resp.Body.Close()
continue
}
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
resp.Body.Close()

var commit commitLong
Expand All @@ -238,20 +310,21 @@ func processGoVersions() {
}

// Generate the code.
f, err = os.Create(goversionOutputFile)
if err != nil {
fmt.Println("Failed to open the file:", err)
return
}
defer f.Close()
buf := bytes.NewBuffer(nil)

goversionTemplate.Execute(f, struct {
err = goversionTemplate.Execute(buf, struct {
Timestamp time.Time
GoVersions map[string]*goversion
}{
Timestamp: time.Now().UTC(),
GoVersions: knownVersions,
})
if err != nil {
fmt.Println("Error when generating the code:", err)
return
}

writeOnDemand(buf.Bytes(), goversionOutputFile)
}

func getStoredGoversions(f *os.File) (map[string]*goversion, error) {
Expand Down Expand Up @@ -307,14 +380,14 @@ func getNextPageURL(r *http.Response) string {

func main() {
processGoVersions()
client := http.DefaultClient

resp, err := client.Get(fmt.Sprintf(requestURLFormatStr, "master"))
if err != nil {
fmt.Println("Error when fetching go src data:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error when reading response body:", err)
return
Expand All @@ -337,24 +410,26 @@ func main() {
if tree.Path == "src" {
continue
}
// Strip "src/" and add to list.
// Strip "src/" and add to the list.
stdPkgs = append(stdPkgs, strings.TrimPrefix(tree.Path, "src/"))
}

f, err := os.Create(outputFile)
if err != nil {
fmt.Println("Failed to open the file:", err)
return
}
defer f.Close()
// Generate the code.
buf := bytes.NewBuffer(nil)

packageTemplate.Execute(f, struct {
err = packageTemplate.Execute(buf, struct {
Timestamp time.Time
StdPkg []string
}{
Timestamp: time.Now().UTC(),
StdPkg: stdPkgs,
})
if err != nil {
fmt.Println("Error when generating the code:", err)
return
}

writeOnDemand(buf.Bytes(), outputFile)
}

func skipPath(path string) bool {
Expand Down
Loading
Loading