build(release): add tag-based release automation and version metadata
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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:"
|
||||||
|
|||||||
+12
-11
@@ -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
|
||||||
config.Init()
|
|
||||||
log.Init()
|
|
||||||
dao.Init()
|
|
||||||
mq.Start()
|
|
||||||
go telegram.BotStart()
|
|
||||||
go task.Start()
|
|
||||||
|
|
||||||
if err := command.Execute(); err != nil {
|
func InitApp() {
|
||||||
panic(err)
|
initOnce.Do(func() {
|
||||||
}
|
config.Init()
|
||||||
|
log.Init()
|
||||||
|
dao.Init()
|
||||||
|
mq.Start()
|
||||||
|
go telegram.BotStart()
|
||||||
|
go task.Start()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
+21
-10
@@ -11,15 +11,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
AppDebug bool
|
AppDebug bool
|
||||||
MysqlDns string
|
MysqlDns string
|
||||||
RuntimePath string
|
RuntimePath string
|
||||||
LogSavePath string
|
LogSavePath string
|
||||||
StaticPath string
|
StaticPath string
|
||||||
TgBotToken string
|
TgBotToken string
|
||||||
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
@@ -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()
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user