build(release): add tag-based release automation and version metadata

This commit is contained in:
alphago9
2026-03-30 01:37:08 +08:00
parent fc8d58024e
commit dea81caa61
11 changed files with 312 additions and 69 deletions
+25 -7
View File
@@ -1,28 +1,46 @@
name: docker-alpine-epusdt name: docker-alpine-epusdt
on: on:
workflow_dispatch: #github页面手动触发 workflow_dispatch:
push: push:
branches: [ "main" ] branches:
- "main"
env: env:
IMAGE_NAME: epusdt #这是您的镜像名 IMAGE_NAME: epusdt
jobs: jobs:
push-docker-hub: push-docker-hub:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
TZ: Asia/Shanghai TZ: Asia/Shanghai
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: Compute Build Metadata
id: meta
shell: bash
run: |
echo "version=main-${GITHUB_SHA}" >> "$GITHUB_OUTPUT"
echo "commit=${GITHUB_SHA}" >> "$GITHUB_OUTPUT"
echo "date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
- name: Login - name: Login
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build && Push
uses: docker/build-push-action@v4 - name: Build And Push
uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
push: true push: true
build-args: |
VERSION=${{ steps.meta.outputs.version }}
COMMIT=${{ steps.meta.outputs.commit }}
DATE=${{ steps.meta.outputs.date }}
tags: | tags: |
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:alpine ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:alpine
+62
View File
@@ -0,0 +1,62 @@
name: release
on:
push:
tags:
- "v*"
permissions:
contents: write
id-token: write
attestations: write
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
goreleaser:
name: Build And Publish Binaries
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Ensure Tag Commit Is On Default Branch
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
git fetch origin "$DEFAULT_BRANCH" --depth=1
if ! git merge-base --is-ancestor "$GITHUB_SHA" "origin/$DEFAULT_BRANCH"; then
echo "tag ${GITHUB_REF_NAME} must reference a commit reachable from ${DEFAULT_BRANCH}"
exit 1
fi
- name: Set Up Go
uses: actions/setup-go@v6
with:
go-version-file: src/go.mod
- name: Install Cosign
uses: sigstore/cosign-installer@v4.1.1
- name: Install Syft
uses: anchore/sbom-action/download-syft@v0.24.0
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
distribution: goreleaser
version: "~> v2"
workdir: src
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Attest Release Checksums
uses: actions/attest@v4
with:
subject-checksums: src/dist/epusdt_${{ github.ref_name }}_checksums.txt
+4 -2
View File
@@ -2,13 +2,15 @@ FROM golang:alpine AS builder
RUN apk add --no-cache --update git build-base RUN apk add --no-cache --update git build-base
ENV CGO_ENABLED=1 ENV CGO_ENABLED=1
ARG VERSION=0.0.0-dev
ARG COMMIT=none
ARG DATE=unknown
WORKDIR /app WORKDIR /app
COPY ./src/go.mod ./src/go.sum ./ COPY ./src/go.mod ./src/go.sum ./
RUN go mod download RUN go mod download
COPY ./src . COPY ./src .
RUN go mod tidy \ RUN go build -ldflags "-s -w -X github.com/assimon/luuu/config.BuildVersion=${VERSION} -X github.com/assimon/luuu/config.BuildCommit=${COMMIT} -X github.com/assimon/luuu/config.BuildDate=${DATE}" \
&& go build -ldflags "-s -w" \
-o epusdt . -o epusdt .
FROM alpine:latest AS runner FROM alpine:latest AS runner
+74
View File
@@ -0,0 +1,74 @@
# Releasing
This repository publishes versioned binaries to GitHub Releases when a tag is pushed.
## What gets published
For each tag like `v1.2.3`, GitHub Actions builds release archives for:
- `linux/amd64`
- `linux/arm64`
- `darwin/amd64`
- `darwin/arm64`
- `windows/amd64`
- `windows/arm64`
Each archive includes:
- the `epusdt` binary
- `src/.env.example`
- `src/static/`
Windows artifacts are published as `.zip`. Other platforms are published as `.tar.gz`.
Each release also publishes:
- a checksum file
- a Sigstore keyless signature bundle for the checksum file
- archive SBOM documents generated by Syft
- a GitHub build provenance attestation for the checksum file
## How to cut a release
1. Make sure the release commit has already landed on the default branch.
2. Create an annotated tag:
```bash
git tag -a v1.0.0 -m "release v1.0.0"
```
3. Push the tag:
```bash
git push origin v1.0.0
```
4. Wait for the `release` workflow to finish on GitHub.
5. Download the generated binaries from the GitHub Release page.
## Verify a release
Verify the checksum signature with Cosign:
```bash
cosign verify-blob \
--bundle epusdt_v1.0.0_checksums.txt.sigstore.json \
epusdt_v1.0.0_checksums.txt
```
Verify the GitHub build provenance attestation:
```bash
gh attestation verify epusdt_v1.0.0_checksums.txt -R GMwalletApp/epusdt
```
## Local validation
Install `cosign` and `syft`, then run a snapshot build locally before pushing a tag:
```bash
cd src
go run github.com/goreleaser/goreleaser/v2@latest release --snapshot --clean
```
The resulting artifacts will be generated under `src/dist/`.
+52 -24
View File
@@ -1,44 +1,72 @@
# This is an example .goreleaser.yml file with some sensible defaults. version: 2
# Make sure to check the documentation at https://goreleaser.com
project_name: epusdt project_name: epusdt
before: before:
hooks: hooks:
# You may remove this if you don't use go modules. - go test ./...
#- go mod tidy
# you may remove this if you don't need go generate
#- go generate ./...
builds: builds:
- env: - id: epusdt
main: .
binary: epusdt
env:
- CGO_ENABLED=0 - CGO_ENABLED=0
flags:
- -trimpath
ldflags:
- -s -w -X github.com/assimon/luuu/config.BuildVersion={{ .Version }} -X github.com/assimon/luuu/config.BuildCommit={{ .Commit }} -X github.com/assimon/luuu/config.BuildDate={{ .Date }}
goos: goos:
- darwin
- linux - linux
- darwin
- windows - windows
goarch: goarch:
- amd64 - amd64
- arm - arm64
- 386
archives: archives:
- replacements: - id: epusdt
darwin: Darwin ids:
linux: Linux - epusdt
windows: Windows name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
386: i386
amd64: x86_64
id: epusdt
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
format: tar.gz
files: files:
- .env.example - .env.example
- static/* - static/**
- runtime/* format_overrides:
- goos: windows
formats:
- zip
checksum: checksum:
name_template: 'checksums.txt' name_template: "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
signs:
- cmd: cosign
signature: "${artifact}.sigstore.json"
args:
- "sign-blob"
- "--bundle=${signature}"
- "${artifact}"
- "--yes"
artifacts: checksum
sboms:
- id: archives
artifacts: archive
snapshot: snapshot:
name_template: "{{ incpatch .Version }}-next" name_template: "{{ incpatch .Version }}-next"
release:
github:
owner: GMwalletApp
name: epusdt
changelog: changelog:
sort: asc sort: asc
filters: filters:
exclude: exclude:
- '^docs:' - "^docs:"
- '^test:' - "^test:"
- "^chore:"
- "^ci:"
+7 -6
View File
@@ -1,7 +1,8 @@
package bootstrap package bootstrap
import ( import (
"github.com/assimon/luuu/command" "sync"
"github.com/assimon/luuu/config" "github.com/assimon/luuu/config"
"github.com/assimon/luuu/model/dao" "github.com/assimon/luuu/model/dao"
"github.com/assimon/luuu/mq" "github.com/assimon/luuu/mq"
@@ -10,15 +11,15 @@ import (
"github.com/assimon/luuu/util/log" "github.com/assimon/luuu/util/log"
) )
func Start() { var initOnce sync.Once
func InitApp() {
initOnce.Do(func() {
config.Init() config.Init()
log.Init() log.Init()
dao.Init() dao.Init()
mq.Start() mq.Start()
go telegram.BotStart() go telegram.BotStart()
go task.Start() go task.Start()
})
if err := command.Execute(); err != nil {
panic(err)
}
} }
+18
View File
@@ -0,0 +1,18 @@
package command
import (
"github.com/assimon/luuu/config"
"github.com/gookit/color"
)
func printBanner() {
color.Green.Printf("%s\n", " _____ _ _ \n | ____|_ __ _ _ ___ __| | |_ \n | _| | '_ \\| | | / __|/ _` | __|\n | |___| |_) | |_| \\__ \\ (_| | |_ \n |_____| .__/ \\__,_|___/\\__,_|\\__|\n |_| ")
color.Infof(
"Epusdt version(%s) commit(%s) built(%s) Powered by %s %s \n",
config.GetAppVersion(),
config.GetBuildCommit(),
config.GetBuildDate(),
"GMwalletApp",
"https://github.com/GMwalletApp/epusdt",
)
}
+8 -4
View File
@@ -2,6 +2,12 @@ package command
import ( import (
"context" "context"
"net/http"
"os"
"os/signal"
"time"
"github.com/assimon/luuu/bootstrap"
"github.com/assimon/luuu/config" "github.com/assimon/luuu/config"
"github.com/assimon/luuu/middleware" "github.com/assimon/luuu/middleware"
"github.com/assimon/luuu/route" "github.com/assimon/luuu/route"
@@ -12,10 +18,6 @@ import (
echoMiddleware "github.com/labstack/echo/v4/middleware" echoMiddleware "github.com/labstack/echo/v4/middleware"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"net/http"
"os"
"os/signal"
"time"
) )
var httpCmd = &cobra.Command{ var httpCmd = &cobra.Command{
@@ -35,6 +37,8 @@ var startCmd = &cobra.Command{
Short: "启动", Short: "启动",
Long: "启动http服务", Long: "启动http服务",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
bootstrap.InitApp()
printBanner()
HttpServerStart() HttpServerStart()
}, },
} }
+26
View File
@@ -0,0 +1,26 @@
package command
import (
"fmt"
"github.com/assimon/luuu/config"
"github.com/spf13/cobra"
)
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print build version information",
RunE: func(cmd *cobra.Command, args []string) error {
_, err := fmt.Fprintf(cmd.OutOrStdout(),
"version: %s\ncommit: %s\nbuilt: %s\n",
config.GetAppVersion(),
config.GetBuildCommit(),
config.GetBuildDate(),
)
return err
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}
+12 -1
View File
@@ -20,6 +20,9 @@ var (
TgProxy string TgProxy string
TgManage int64 TgManage int64
UsdtRate float64 UsdtRate float64
BuildVersion = "0.0.0-dev"
BuildCommit = "none"
BuildDate = "unknown"
) )
func Init() { func Init() {
@@ -65,7 +68,15 @@ func mustMkdir(path string) {
} }
func GetAppVersion() string { func GetAppVersion() string {
return "0.0.2" return BuildVersion
}
func GetBuildCommit() string {
return BuildCommit
}
func GetBuildDate() string {
return BuildDate
} }
func GetAppName() string { func GetAppName() string {
+4 -5
View File
@@ -1,8 +1,7 @@
package main package main
import ( import (
"github.com/assimon/luuu/bootstrap" "github.com/assimon/luuu/command"
"github.com/assimon/luuu/config"
"github.com/gookit/color" "github.com/gookit/color"
) )
@@ -12,7 +11,7 @@ func main() {
color.Error.Println("[Start Server Err!!!] ", err) color.Error.Println("[Start Server Err!!!] ", err)
} }
}() }()
color.Green.Printf("%s\n", " _____ _ _ \n | ____|_ __ _ _ ___ __| | |_ \n | _| | '_ \\| | | / __|/ _` | __|\n | |___| |_) | |_| \\__ \\ (_| | |_ \n |_____| .__/ \\__,_|___/\\__,_|\\__|\n |_| ") if err := command.Execute(); err != nil {
color.Infof("Epusdt version(%s) Powered by %s %s \n", config.GetAppVersion(), "GMwalletApp", "https://github.com/GMwalletApp/epusdt") panic(err)
bootstrap.Start() }
} }