From 5d548e40cf988fe85ef1466b0b9b347121eba022 Mon Sep 17 00:00:00 2001 From: xhd2015 Date: Sun, 19 May 2024 10:30:48 +0800 Subject: [PATCH] add push-master workflow --- .github/workflows/check.yml | 46 ++++++++++ .github/workflows/go.yml | 30 +------ .github/workflows/pre-master.yml | 63 ++++++++++++++ cmd/xgo/runtime_gen/core/version.go | 4 +- cmd/xgo/version.go | 4 +- runtime/core/version.go | 4 +- script/build-release/fixup.go | 3 +- script/build-release/revision/revision.go | 101 ++++++++++++++++------ script/git-hooks/main.go | 48 ++++++++-- 9 files changed, 235 insertions(+), 68 deletions(-) create mode 100644 .github/workflows/check.yml create mode 100644 .github/workflows/pre-master.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 00000000..075004e8 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,46 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +name: Check + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master", "pre-master" ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Check spelling of files + uses: crate-ci/typos@master + continue-on-error: false + with: + files: ./ + + - name: Set up Go1.17 + uses: actions/setup-go@v4 + with: + go-version: '1.17' + + - name: Check Binary Install + continue-on-error: false + run: | + curl -fsSL https://github.com/xhd2015/xgo/raw/master/script/install/install.sh | env INSTALL_TO_BIN=true bash -x + xgo revision + + - name: Build + run: go build -o /dev/null -v ./cmd/xgo + + - name: Build Release + run: go run ./script/build-release --include-install-src --include-local + + - name: Check Revesion + run: ~/.xgo/bin/xgo revision + + - name: Check Go Version + run: ~/.xgo/bin/xgo exec go version \ No newline at end of file diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0839a338..5c33da80 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -7,7 +7,7 @@ on: push: branches: [ "master" ] pull_request: - branches: [ "master" ] + branches: [ "master", "pre-master" ] jobs: @@ -22,23 +22,6 @@ jobs: go-version: '1.20' cache: false - - name: Check spelling of files - uses: crate-ci/typos@master - continue-on-error: false - with: - files: ./ - - - name: Binary Install - continue-on-error: false - run: curl -fsSL https://github.com/xhd2015/xgo/raw/master/script/install/install.sh | env INSTALL_TO_BIN=true bash -x - - - name: Check Binary Install - continue-on-error: false - run: xgo revision - - - name: Build - run: go build -o /dev/null -v ./cmd/xgo - - name: Test run: go run ./script/run-test --reset-instrument --debug -v -cover -coverpkg github.com/xhd2015/xgo/runtime/... -coverprofile cover.out @@ -46,13 +29,4 @@ jobs: run: go run ./cmd/go-tool-coverage merge ./cover-runtime.out ./cover-runtime-sub.out -o cover-runtime-merged.out --exclude-prefix github.com/xhd2015/xgo/runtime/test - name: Print coverage - run: cd runtime && go tool cover --func ../cover-runtime-merged.out - - - name: Build Release - run: go run ./script/build-release --include-install-src --include-local - - - name: Check Version - run: ~/.xgo/bin/xgo revision - - - name: Check Go Version - run: ~/.xgo/bin/xgo exec go version \ No newline at end of file + run: cd runtime && go tool cover --func ../cover-runtime-merged.out \ No newline at end of file diff --git a/.github/workflows/pre-master.yml b/.github/workflows/pre-master.yml new file mode 100644 index 00000000..2bb9284f --- /dev/null +++ b/.github/workflows/pre-master.yml @@ -0,0 +1,63 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +# This workflow run pre-commit and amend version and commit info +# Before merging into master + +name: Pre Master + +on: + push: + branches: [ "pre-master" ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' + cache: false + + - name: Ensure HEAD~1 Same With Master + run: | + set -x + cur_branch=$(git branch --show-current) + if [[ $cur_branch != pre-master ]];then + echo "expect branch on pre-master, actual: $cur_branch" >&2 + exit 1 + fi + git fetch origin master + master_commit=$(git rev-parse origin/master) + head_parent_commit=$(git rev-parse HEAD~1) + if [[ $master_commit != $head_parent_commit ]];then + echo "HEAD~1 differs with origin/master" >&2 + exit 1 + fi + + - name: Run Git Hooks + run: | + set -x + echo 'before' + cat cmd/xgo/version.go + go run ./script/git-hooks pre-commit --amend --no-commit + git status + echo 'after' + cat cmd/xgo/version.go + + - name: Push Changes To Master + run: | + git add -A + git config --local user.email "$(git log --format=%ae -n1 HEAD)" + git config --local user.name "$(git log --format=%an -n1 HEAD)" + git commit --amend --no-edit --no-verify + git status + git push origin HEAD:master -f \ No newline at end of file diff --git a/cmd/xgo/runtime_gen/core/version.go b/cmd/xgo/runtime_gen/core/version.go index 159f8e11..aca7e833 100755 --- a/cmd/xgo/runtime_gen/core/version.go +++ b/cmd/xgo/runtime_gen/core/version.go @@ -7,8 +7,8 @@ import ( ) const VERSION = "1.0.35" -const REVISION = "61cf57819a9977020a457c10b44c8aa881984fd8+1" -const NUMBER = 219 +const REVISION = "c490c2dbaaecd04df3888542f830cb715dd9b285+1" +const NUMBER = 220 // these fields will be filled by compiler const XGO_VERSION = "" diff --git a/cmd/xgo/version.go b/cmd/xgo/version.go index 66ed53b3..b8fe2858 100644 --- a/cmd/xgo/version.go +++ b/cmd/xgo/version.go @@ -3,8 +3,8 @@ package main import "fmt" const VERSION = "1.0.35" -const REVISION = "61cf57819a9977020a457c10b44c8aa881984fd8+1" -const NUMBER = 219 +const REVISION = "c490c2dbaaecd04df3888542f830cb715dd9b285+1" +const NUMBER = 220 func getRevision() string { revSuffix := "" diff --git a/runtime/core/version.go b/runtime/core/version.go index 159f8e11..aca7e833 100644 --- a/runtime/core/version.go +++ b/runtime/core/version.go @@ -7,8 +7,8 @@ import ( ) const VERSION = "1.0.35" -const REVISION = "61cf57819a9977020a457c10b44c8aa881984fd8+1" -const NUMBER = 219 +const REVISION = "c490c2dbaaecd04df3888542f830cb715dd9b285+1" +const NUMBER = 220 // these fields will be filled by compiler const XGO_VERSION = "" diff --git a/script/build-release/fixup.go b/script/build-release/fixup.go index ad2770c7..83d692f3 100644 --- a/script/build-release/fixup.go +++ b/script/build-release/fixup.go @@ -27,6 +27,7 @@ func stageFile(file string) (restore func() error, err error) { }, nil } +// NOTE: only commit is updated, version number not touched func updateRevisions(targetDir string, unlink bool, rev string) (restore func() error, err error) { // unlink files because all files are symlink files := revision.GetVersionFiles(targetDir) @@ -54,7 +55,7 @@ func updateRevisions(targetDir string, unlink bool, rev string) (restore func() } for _, file := range files { - err := revision.PatchVersionFile(file, rev, false) + err := revision.PatchVersionFile(file, rev, false, -1) if err != nil { return restore, err } diff --git a/script/build-release/revision/revision.go b/script/build-release/revision/revision.go index 4a46101d..b05ab6c4 100644 --- a/script/build-release/revision/revision.go +++ b/script/build-release/revision/revision.go @@ -13,14 +13,22 @@ import ( func GetCommitHash(dir string, ref string) (string, error) { var args []string - if dir != "" { - args = append(args, "-C", dir) - } args = append(args, "log", "--format=%H", "-1") if ref != "" { args = append(args, ref) } - return cmd.Output("git", args...) + return cmd.Dir(dir).Output("git", args...) +} + +// git cat-file -p REF:FILE +func GetFileContent(dir string, ref string, file string) (string, error) { + if ref == "" { + return "", fmt.Errorf("requires ref") + } + if file == "" { + return "", fmt.Errorf("requires file") + } + return cmd.Dir(dir).Output("git", "cat-file", "-p", fmt.Sprintf("%s:%s", ref, file)) } func ReplaceRevision(s string, revision string) (string, error) { @@ -43,37 +51,65 @@ func ReplaceRevision(s string, revision string) (string, error) { return replaceSequence(s, []string{"const", "REVISION", "="}, replaceLine) } +var constNumberSeq = []string{"const", "NUMBER", "="} + func IncrementNumber(s string) (string, error) { + return replaceOrIncrementNumber(s, -1) +} +func replaceOrIncrementNumber(s string, version int) (string, error) { replaceLine := func(line string, index int) (string, error) { - isDigit := func(r rune) bool { - return '0' <= r && r <= '9' + start, end, num, err := parseNum(line[index:]) + if err != nil { + return "", fmt.Errorf("line %q: %w", line, err) } - start := strings.IndexFunc(line[index+1:], isDigit) - if start < 0 { - return "", fmt.Errorf("no number found: %s", line) + start += index + end += index + if version < 0 { + version = num + 1 } - start += index + 1 - end := strings.LastIndexFunc(line[start:], isDigit) - if end < 0 { - return "", fmt.Errorf("no number found: %s", line) - } - end += start + 1 + return line[:start] + strconv.Itoa(version) + line[end:], nil + } + return replaceSequence(s, constNumberSeq, replaceLine) +} - numStr := line[start:end] +func isDigit(r rune) bool { + return '0' <= r && r <= '9' +} - num, err := strconv.ParseInt(numStr, 10, 64) - if err != nil { - return "", fmt.Errorf("invalid number %s: %w", line, err) - } - newNum := num + 1 - return line[:start] + strconv.FormatInt(newNum, 10) + line[end:], nil +func parseNum(str string) (start int, end int, num int, err error) { + start = strings.IndexFunc(str, isDigit) + if start < 0 { + return 0, 0, 0, fmt.Errorf("no number found") + } + + end = strings.LastIndexFunc(str[start+1:], isDigit) + if end < 0 { + return 0, 0, 0, fmt.Errorf("no number found") } - return replaceSequence(s, []string{"const", "NUMBER", "="}, replaceLine) + end += start + 2 + + numStr := str[start:end] + + num, err = strconv.Atoi(numStr) + if err != nil { + return 0, 0, 0, fmt.Errorf("invalid number: %w", err) + } + return start, end, int(num), nil } -func replaceSequence(s string, seq []string, replaceLine func(line string, index int) (string, error)) (string, error) { +func GetVersionNumber(s string) (int, error) { + // const NUMBER = lines := strings.Split(s, "\n") + lineIdx, byteIdx := IndexLinesSequence(lines, constNumberSeq) + if lineIdx < 0 { + return 0, fmt.Errorf("sequence %v not found", constNumberSeq) + } + _, _, num, err := parseNum(lines[lineIdx][byteIdx:]) + return num, err +} + +func IndexLinesSequence(lines []string, seq []string) (lineIndex int, byteIndex int) { n := len(lines) lineIdx := -1 byteIdx := -1 @@ -86,6 +122,14 @@ func replaceSequence(s string, seq []string, replaceLine func(line string, index break } } + if lineIdx < 0 { + return -1, -1 + } + return lineIdx, byteIdx +} +func replaceSequence(s string, seq []string, replaceLine func(line string, index int) (string, error)) (string, error) { + lines := strings.Split(s, "\n") + lineIdx, byteIdx := IndexLinesSequence(lines, seq) if lineIdx < 0 { return "", fmt.Errorf("sequence %v not found", seq) } @@ -98,14 +142,19 @@ func replaceSequence(s string, seq []string, replaceLine func(line string, index return strings.Join(lines, "\n"), nil } -func PatchVersionFile(file string, rev string, incrementNumber bool) error { +func PatchVersionFile(file string, rev string, autIncrementNumber bool, version int) error { err := fileutil.Patch(file, func(data []byte) ([]byte, error) { content := string(data) newContent, err := ReplaceRevision(content, rev) if err != nil { return nil, err } - if incrementNumber { + if version > 0 { + newContent, err = replaceOrIncrementNumber(newContent, version) + if err != nil { + return nil, err + } + } else if autIncrementNumber { newContent, err = IncrementNumber(newContent) if err != nil { return nil, err diff --git a/script/git-hooks/main.go b/script/git-hooks/main.go index 4edfd45f..5a37e6cc 100644 --- a/script/git-hooks/main.go +++ b/script/git-hooks/main.go @@ -28,11 +28,16 @@ func main() { var noCommit bool var noUpdateVersion bool + var amend bool for _, arg := range args { if arg == "--no-commit" { noCommit = true continue } + if arg == "--amend" { + amend = true + continue + } if arg == "--no-update-version" { noUpdateVersion = true continue @@ -52,7 +57,7 @@ func main() { if cmd == "install" { err = install() } else if cmd == "pre-commit" { - err = preCommitCheck(noCommit, noUpdateVersion) + err = preCommitCheck(noCommit, amend, noUpdateVersion) } else if cmd == "post-commit" { err = postCommitCheck(noCommit) } else { @@ -66,12 +71,24 @@ func main() { } const preCommitCmdHead = "# xgo check" -const preCommitCmd = "go run ./script/git-hooks pre-commit" + +// NOTE: no empty lines in between +const preCommitCmd = `# see: https://stackoverflow.com/questions/19387073/how-to-detect-commit-amend-by-pre-commit-hook +is_amend=$(ps -ocommand= -p $PPID | grep -e '--amend') +# echo "is amend: $is_amend" +# args is always empty +# echo "args: ${args[@]}" +flags=() +if [[ -n $is_amend ]];then + flags=("${flags[@]}" --amend) +fi +go run ./script/git-hooks pre-commit "${flags[@]}" +` const postCommitCmdHead = "# xgo check" const postCommitCmd = "go run ./script/git-hooks post-commit" -func preCommitCheck(noCommit bool, noUpdateVersion bool) error { +func preCommitCheck(noCommit bool, amend bool, noUpdateVersion bool) error { gitDir, err := git.ShowTopLevel("") if err != nil { return err @@ -84,7 +101,11 @@ func preCommitCheck(noCommit bool, noUpdateVersion bool) error { var affectedFiles []string const updateRevision = true if updateRevision { - commitHash, err := revision.GetCommitHash("", "HEAD") + refLast := "HEAD" + if amend { + refLast = "HEAD~1" + } + commitHash, err := revision.GetCommitHash(rootDir, refLast) if err != nil { return err } @@ -95,13 +116,25 @@ func preCommitCheck(noCommit bool, noUpdateVersion bool) error { // suffix "+1" to indicate this rev := commitHash + "+1" - versionFiles := revision.GetVersionFiles(rootDir) - for _, file := range versionFiles { - err = revision.PatchVersionFile(file, rev, !noUpdateVersion) + relVersionFiles := revision.GetVersionFiles("") + versionFiles := make([]string, 0, len(relVersionFiles)) + for _, relFile := range relVersionFiles { + file := filepath.Join(rootDir, relFile) + versionFiles = append(versionFiles, file) + content, err := revision.GetFileContent(rootDir, commitHash, relFile) + if err != nil { + return err + } + version, err := revision.GetVersionNumber(content) + if err != nil { + return err + } + err = revision.PatchVersionFile(file, rev, !noUpdateVersion, version+1) if err != nil { return err } } + affectedFiles = append(affectedFiles, versionFiles...) } @@ -133,6 +166,7 @@ func postCommitCheck(noCommit bool) error { } func install() error { + // NOTE: is git dir, not toplevel dir when in worktree mode gitDir, err := git.GetGitDir("") if err != nil { return err