Skip to content

Commit cd45651

Browse files
authored
feat: Add gopy version command & release-please pipeline (#402)
* Add gopy version command & release automation - Validate CI config & test ldflags version stamping - Drop package-name from release-please config to avoid component-prefixed tags * Fix Windows CI failure in TestVersionLdflags go build silently appends .exe on Windows, so exec of the bare name failed
1 parent 4c1823a commit cd45651

13 files changed

Lines changed: 343 additions & 50 deletions
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: GoReleaser Check
2+
3+
# Validates .goreleaser.yaml against a real snapshot build (cross-compile +
4+
# archive generation, no publish) so config/toolchain regressions surface on
5+
# the PR instead of after release-please has already cut a tag & GitHub
6+
# Release. See release-please.yml's `publish` job, which runs the real
7+
# `goreleaser release --clean` only after that release already exists.
8+
9+
on:
10+
pull_request:
11+
branches: [ '**' ]
12+
paths:
13+
- '.goreleaser.yaml'
14+
- '.github/workflows/goreleaser-check.yml'
15+
- '.github/workflows/release-please.yml'
16+
- 'go.mod'
17+
- 'go.sum'
18+
- 'version.go'
19+
workflow_dispatch:
20+
21+
jobs:
22+
snapshot:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0
29+
30+
- name: Install Go
31+
uses: actions/setup-go@v5
32+
with:
33+
go-version-file: go.mod
34+
cache: true
35+
36+
- name: Validate GoReleaser config
37+
uses: goreleaser/goreleaser-action@v6
38+
with:
39+
distribution: goreleaser
40+
version: latest
41+
args: check
42+
43+
- name: Snapshot build (validates cross-compilation & archives)
44+
uses: goreleaser/goreleaser-action@v6
45+
with:
46+
distribution: goreleaser
47+
version: latest
48+
args: release --snapshot --clean
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Release Please
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
release-please:
15+
runs-on: ubuntu-latest
16+
outputs:
17+
releases_created: ${{ steps.release.outputs.releases_created }}
18+
tag_name: ${{ steps.release.outputs.tag_name }}
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- uses: googleapis/release-please-action@v5
23+
id: release
24+
with:
25+
config-file: .release-please-config.json
26+
manifest-file: .release-please-manifest.json
27+
target-branch: master
28+
29+
# Build & publish binaries only when release-please actually cut a release
30+
# (i.e. a release-please PR was just merged to master).
31+
publish:
32+
needs: release-please
33+
if: ${{ needs.release-please.outputs.releases_created == 'true' }}
34+
runs-on: ubuntu-latest
35+
permissions:
36+
contents: write
37+
steps:
38+
- name: Checkout code
39+
uses: actions/checkout@v4
40+
with:
41+
ref: ${{ needs.release-please.outputs.tag_name }}
42+
fetch-depth: 0
43+
44+
- name: Install Go
45+
uses: actions/setup-go@v5
46+
with:
47+
go-version-file: go.mod
48+
cache: true
49+
50+
- name: Run GoReleaser
51+
uses: goreleaser/goreleaser-action@v6
52+
with:
53+
distribution: goreleaser
54+
version: latest
55+
# release-please already created the GitHub Release (notes, tag);
56+
# GoReleaser just builds & uploads the binary archives to it.
57+
args: release --clean
58+
env:
59+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
# IDE files
22
.idea/
33
*.iml
4+
5+
# goreleaser build output
6+
/dist/

‎.goreleaser.yaml‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
version: 2
2+
project_name: gopy
3+
4+
before:
5+
hooks:
6+
- go mod tidy
7+
8+
builds:
9+
- id: gopy
10+
main: .
11+
binary: gopy
12+
env:
13+
- CGO_ENABLED=0
14+
goos: [linux, darwin, windows]
15+
goarch: [amd64, arm64]
16+
ldflags:
17+
- -s -w
18+
- -X main.GitCommit={{ .ShortCommit }}
19+
- -X 'main.VersionDate={{ .CommitDate }} UTC'
20+
21+
archives:
22+
- id: gopy
23+
formats: [tar.gz]
24+
format_overrides:
25+
- goos: windows
26+
formats: [zip]
27+
name_template: >-
28+
{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}
29+
30+
checksum:
31+
name_template: "checksums.txt"
32+
33+
changelog:
34+
sort: asc
35+
filters:
36+
exclude:
37+
- "^docs:"
38+
- "^test:"
39+
- "^ci:"
40+
- "^Merge pull request"
41+
42+
release:
43+
github:
44+
owner: go-python
45+
name: gopy
46+
# release-please already created the GitHub Release for this tag (with its
47+
# own changelog-derived notes); keep those notes as-is and just attach
48+
# the built archives/checksums to it.
49+
mode: keep-existing
50+
prerelease: auto
51+
name_template: "{{ .Tag }}"

‎.release-please-config.json‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"release-type": "go",
3+
"include-v-in-tag": true,
4+
"bootstrap-sha": "d09ff0f8254c8bd4a131157bf276c83330930cb5",
5+
"packages": {
6+
".": {
7+
"release-type": "go",
8+
"changelog-path": "CHANGELOG.md",
9+
"extra-files": [
10+
{
11+
"path": "version.go",
12+
"type": "generic"
13+
}
14+
]
15+
}
16+
},
17+
"changelog-sections": [
18+
{ "type": "feat", "section": "Features", "hidden": false },
19+
{ "type": "fix", "section": "Bug Fixes", "hidden": false },
20+
{ "type": "perf", "section": "Performance Improvements", "hidden": false },
21+
{ "type": "revert", "section": "Reverts", "hidden": false },
22+
{ "type": "docs", "section": "Documentation", "hidden": false },
23+
{ "type": "style", "section": "Styles", "hidden": true },
24+
{ "type": "chore", "section": "Miscellaneous Chores", "hidden": true },
25+
{ "type": "refactor", "section": "Code Refactoring", "hidden": false },
26+
{ "type": "test", "section": "Tests", "hidden": true },
27+
{ "type": "build", "section": "Build System", "hidden": false },
28+
{ "type": "ci", "section": "Continuous Integration", "hidden": true }
29+
]
30+
}

‎.release-please-manifest.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
".": "0.4.10"
3+
}

‎Makefile‎

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ DIRS=`go list ./...`
1111
PYTHON=python3
1212
PIP=$(PYTHON) -m pip
1313

14+
GIT_COMMIT=`git rev-parse --short HEAD`
15+
VERS_DATE=`date -u +%Y-%m-%d\ %H:%M`
16+
LDFLAGS=-X 'main.GitCommit=$(GIT_COMMIT)' -X 'main.VersionDate=$(VERS_DATE) UTC'
17+
1418
all: build
1519

16-
build:
20+
build:
1721
@echo "GO111MODULE = $(value GO111MODULE)"
18-
$(GOBUILD) -v $(DIRS)
22+
$(GOBUILD) -v -ldflags "$(LDFLAGS)" $(DIRS)
1923

2024
test:
2125
@echo "GO111MODULE = $(value GO111MODULE)"
@@ -52,30 +56,7 @@ prereq:
5256
@echo " _PyInit__gi, referenced from:..."
5357
@echo
5458

55-
56-
# NOTE: MUST update version number here prior to running 'make release' and edit this file!
57-
VERS=v0.4.10
58-
PACKAGE=main
59-
GIT_COMMIT=`git rev-parse --short HEAD`
60-
VERS_DATE=`date -u +%Y-%m-%d\ %H:%M`
61-
VERS_FILE=version.go
62-
63-
release:
64-
/bin/rm -f $(VERS_FILE)
65-
@echo "// WARNING: auto-generated by Makefile release target -- run 'make release' to update" > $(VERS_FILE)
66-
@echo "" >> $(VERS_FILE)
67-
@echo "package $(PACKAGE)" >> $(VERS_FILE)
68-
@echo "" >> $(VERS_FILE)
69-
@echo "const (" >> $(VERS_FILE)
70-
@echo " Version = \"$(VERS)\"" >> $(VERS_FILE)
71-
@echo " GitCommit = \"$(GIT_COMMIT)\" // the commit JUST BEFORE the release" >> $(VERS_FILE)
72-
@echo " VersionDate = \"$(VERS_DATE)\" // UTC" >> $(VERS_FILE)
73-
@echo ")" >> $(VERS_FILE)
74-
@echo "" >> $(VERS_FILE)
75-
goimports -w $(VERS_FILE)
76-
/bin/cat $(VERS_FILE)
77-
git commit -am "$(VERS) release"
78-
git tag -a $(VERS) -m "$(VERS) release"
79-
git push
80-
git push origin --tags
59+
# Releases are managed by release-please (.github/workflows/release-please.yml):
60+
# merging its release PR to master bumps version.go, tags the commit, and
61+
# publishes the GitHub Release. GoReleaser then builds & uploads binaries to it.
8162

‎bind/bind.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ type BindCfg struct {
2828
PkgPrefix string
2929
// rename Go exported symbols to python PEP snake_case
3030
RenameCase bool
31+
// gopy version string embedded in this binary, stamped into generated
32+
// file headers so output can be traced back to the release that produced it
33+
Version string
3134
}
3235

3336
// ErrorList is a list of errors

‎bind/gen.go‎

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ var WindowsOS = false
3838

3939
// for all preambles: 1 = name of package (outname), 2 = cmdstr
4040

41-
// 3 = libcfg, 4 = GoHandle, 5 = CGoHandle, 6 = all imports, 7 = mainstr, 8 = exe pre C, 9 = exe pre go
41+
// 3 = libcfg, 4 = GoHandle, 5 = CGoHandle, 6 = all imports, 7 = mainstr, 8 = exe pre C, 9 = exe pre go, 10 = gopy version
4242
const (
4343
goPreamble = `/*
4444
cgo stubs for package %[1]s.
45-
File is generated by gopy. Do not edit.
45+
File is generated by gopy version %[10]s. Do not edit.
4646
%[2]s
4747
*/
4848
@@ -263,8 +263,9 @@ func GoPyMainRun() {
263263
264264
`
265265

266+
// 3 = gopy version
266267
PyBuildPreamble = `# python build stubs for package %[1]s
267-
# File is generated by gopy. Do not edit.
268+
# File is generated by gopy version %[3]s. Do not edit.
268269
# %[2]s
269270
270271
from pybindgen import retval, param, Function, Module
@@ -317,11 +318,11 @@ mod.add_function('_gopy_clear_go_tls', None, [])
317318
// appended to imports in py wrap preamble as key for adding at end
318319
importHereKeyString = "%%%%%%<<<<<<ADDIMPORTSHERE>>>>>>>%%%%%%%"
319320

320-
// 3 = specific package name, 4 = spec pkg path, 5 = doc, 6 = imports
321+
// 3 = specific package name, 4 = spec pkg path, 5 = doc, 6 = imports, 8 = gopy version
321322
PyWrapPreamble = `%[5]s
322323
# python wrapper for package %[4]s within overall package %[1]s
323324
# This is what you import to use the package.
324-
# File is generated by gopy. Do not edit.
325+
# File is generated by gopy version %[8]s. Do not edit.
325326
# %[2]s
326327
327328
# the following is required to enable dlopen to open the _go.so file
@@ -379,11 +380,11 @@ except Exception:
379380
`
380381

381382
// exe version of preamble -- doesn't need complex code to load _ module
382-
// 3 = specific package name, 4 = spec pkg path, 5 = doc, 6 = imports
383+
// 3 = specific package name, 4 = spec pkg path, 5 = doc, 6 = imports, 8 = gopy version
383384
PyWrapExePreamble = `%[5]s
384385
# python wrapper for package %[4]s within standalone executable package %[1]s
385386
# This is what you import to use the package.
386-
# File is generated by gopy. Do not edit.
387+
# File is generated by gopy version %[8]s. Do not edit.
387388
# %[2]s
388389
389390
import collections
@@ -431,9 +432,9 @@ def Init():
431432
`
432433

433434
// 3 = gencmd, 4 = vm, 5 = libext 6 = extraGccArgs, 7 = CFLAGS, 8 = LDLFAGS,
434-
// 9 = windows special declspec hack
435+
// 9 = windows special declspec hack, 10 = gopy version
435436
MakefileTemplate = `# Makefile for python interface for package %[1]s.
436-
# File is generated by gopy. Do not edit.
437+
# File is generated by gopy version %[10]s. Do not edit.
437438
# %[2]s
438439
439440
GOCMD=go
@@ -470,9 +471,9 @@ build:
470471
471472
`
472473

473-
// exe version of template: 3 = gencmd, 4 = vm, 5 = libext
474+
// exe version of template: 3 = gencmd, 4 = vm, 5 = libext, 8 = gopy version
474475
MakefileExeTemplate = `# Makefile for python interface for standalone executable package %[1]s.
475-
# File is generated by gopy. Do not edit.
476+
# File is generated by gopy version %[8]s. Do not edit.
476477
# %[2]s
477478
478479
GOCMD=go
@@ -721,12 +722,12 @@ func (g *pyGen) genGoPreamble() {
721722
exeprego = goExePreambleGo
722723
}
723724
g.gofile.Printf(goPreamble, g.cfg.Name, g.cfg.Cmd, libcfg, GoHandle, CGoHandle,
724-
pkgimport, g.cfg.Main, exeprec, exeprego)
725+
pkgimport, g.cfg.Main, exeprec, exeprego, g.cfg.Version)
725726
g.gofile.Printf("\n// --- generated code for package: %[1]s below: ---\n\n", g.cfg.Name)
726727
}
727728

728729
func (g *pyGen) genPyBuildPreamble() {
729-
g.pybuild.Printf(PyBuildPreamble, g.cfg.Name, g.cfg.Cmd)
730+
g.pybuild.Printf(PyBuildPreamble, g.cfg.Name, g.cfg.Cmd, g.cfg.Version)
730731
}
731732

732733
func (g *pyGen) genPyWrapPreamble() {
@@ -784,9 +785,9 @@ func (g *pyGen) genPyWrapPreamble() {
784785
impstr += importHereKeyString
785786

786787
if g.mode == ModeExe {
787-
g.pywrap.Printf(PyWrapExePreamble, g.cfg.Name, g.cfg.Cmd, n, pkgimport, pkgDoc, impgenstr, impstr)
788+
g.pywrap.Printf(PyWrapExePreamble, g.cfg.Name, g.cfg.Cmd, n, pkgimport, pkgDoc, impgenstr, impstr, g.cfg.Version)
788789
} else {
789-
g.pywrap.Printf(PyWrapPreamble, g.cfg.Name, g.cfg.Cmd, n, pkgimport, pkgDoc, impgenstr, impstr)
790+
g.pywrap.Printf(PyWrapPreamble, g.cfg.Name, g.cfg.Cmd, n, pkgimport, pkgDoc, impgenstr, impstr, g.cfg.Version)
790791
}
791792
}
792793

@@ -816,14 +817,14 @@ func (g *pyGen) genMakefile() {
816817
}
817818

818819
if g.mode == ModeExe {
819-
g.makefile.Printf(MakefileExeTemplate, g.cfg.Name, g.cfg.Cmd, gencmd, g.cfg.VM, g.libext, pycfg.CFlags, pycfg.LdFlags)
820+
g.makefile.Printf(MakefileExeTemplate, g.cfg.Name, g.cfg.Cmd, gencmd, g.cfg.VM, g.libext, pycfg.CFlags, pycfg.LdFlags, g.cfg.Version)
820821
} else {
821822
winhack := ""
822823
if WindowsOS {
823824
winhack = fmt.Sprintf(`# windows-only sed hack here to fix pybindgen declaration of PyInit
824825
sed -i "s/ PyInit_/ __declspec(dllexport) PyInit_/g" %s.c`, g.cfg.Name)
825826
}
826-
g.makefile.Printf(MakefileTemplate, g.cfg.Name, g.cfg.Cmd, gencmd, g.cfg.VM, g.libext, g.extraGccArgs, pycfg.CFlags, pycfg.LdFlags, winhack)
827+
g.makefile.Printf(MakefileTemplate, g.cfg.Name, g.cfg.Cmd, gencmd, g.cfg.VM, g.libext, g.extraGccArgs, pycfg.CFlags, pycfg.LdFlags, winhack, g.cfg.Version)
827828
}
828829
}
829830

0 commit comments

Comments
 (0)