diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 8db73b5..460e7bd 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -5,6 +5,8 @@ on: branches: - main - staging + tags: + - 'v*' paths: - '**.go' - 'go.mod' @@ -15,8 +17,9 @@ on: - '.gitea/workflows/build.yml' jobs: - build-and-push: + build-and-push-branches: runs-on: ubuntu-latest + if: github.ref_type == 'branch' steps: - name: Checkout repository @@ -32,6 +35,17 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Set version variables + id: vars + run: | + if [ "${{ github.ref }}" == "refs/heads/main" ]; then + echo "VERSION=dev-main" >> $GITHUB_OUTPUT + else + echo "VERSION=dev-staging" >> $GITHUB_OUTPUT + fi + echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + echo "COMMIT=${{ github.sha }}" >> $GITHUB_OUTPUT + - name: Build and push Docker image for main uses: docker/build-push-action@v6 with: @@ -40,6 +54,10 @@ jobs: tags: | git.fossy.my.id/${{ secrets.DOCKER_USERNAME }}/tunnel-please:latest platforms: linux/amd64,linux/arm64 + build-args: | + VERSION=${{ steps.vars.outputs.VERSION }} + BUILD_DATE=${{ steps.vars.outputs.BUILD_DATE }} + COMMIT=${{ steps.vars.outputs.COMMIT }} if: github.ref == 'refs/heads/main' - name: Build and push Docker image for staging @@ -50,4 +68,61 @@ jobs: tags: | git.fossy.my.id/${{ secrets.DOCKER_USERNAME }}/tunnel-please:staging platforms: linux/amd64,linux/arm64 - if: github.ref == 'refs/heads/staging' \ No newline at end of file + build-args: | + VERSION=${{ steps.vars.outputs.VERSION }} + BUILD_DATE=${{ steps.vars.outputs.BUILD_DATE }} + COMMIT=${{ steps.vars.outputs.COMMIT }} + if: github.ref == 'refs/heads/staging' + + build-and-push-tags: + runs-on: ubuntu-latest + if: github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v') + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + registry: git.fossy.my.id + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract version and determine release type + id: version + run: | + VERSION=${GITHUB_REF#refs/tags/v} + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + echo "COMMIT=${{ github.sha }}" >> $GITHUB_OUTPUT + + if echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then + if echo "$VERSION" | grep -q '-'; then + echo "IS_PRERELEASE=true" >> $GITHUB_OUTPUT + echo "ADDITIONAL_TAG=staging" >> $GITHUB_OUTPUT + else + echo "IS_PRERELEASE=false" >> $GITHUB_OUTPUT + echo "ADDITIONAL_TAG=latest" >> $GITHUB_OUTPUT + fi + else + echo "Invalid version format: $VERSION" + exit 1 + fi + + - name: Build and push Docker image for release + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + git.fossy.my.id/${{ secrets.DOCKER_USERNAME }}/tunnel-please:v${{ steps.version.outputs.VERSION }} + git.fossy.my.id/${{ secrets.DOCKER_USERNAME }}/tunnel-please:${{ steps.version.outputs.ADDITIONAL_TAG }} + platforms: linux/amd64,linux/arm64 + build-args: | + VERSION=${{ steps.version.outputs.VERSION }} + BUILD_DATE=${{ steps.version.outputs.BUILD_DATE }} + COMMIT=${{ steps.version.outputs.COMMIT }} diff --git a/Dockerfile b/Dockerfile index 9884c52..e0e8bef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,9 @@ FROM golang:1.25.5-alpine AS go_builder +ARG VERSION=dev +ARG BUILD_DATE=unknown +ARG COMMIT=unknown + RUN apk update && apk upgrade && \ apk add --no-cache ca-certificates tzdata git && \ update-ca-certificates @@ -18,7 +22,7 @@ RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ CGO_ENABLED=0 GOOS=linux \ go build -trimpath \ - -ldflags="-w -s" \ + -ldflags="-w -s -X tunnel_pls/version.Version=${VERSION} -X tunnel_pls/version.BuildDate=${BUILD_DATE} -X tunnel_pls/version.Commit=${COMMIT}" \ -o /app/tunnel_pls \ . @@ -28,6 +32,10 @@ RUN adduser -D -u 10001 -g '' appuser && \ FROM scratch +ARG VERSION=dev +ARG BUILD_DATE=unknown +ARG COMMIT=unknown + COPY --from=go_builder /usr/share/zoneinfo /usr/share/zoneinfo COPY --from=go_builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=go_builder /etc/passwd /etc/passwd @@ -43,6 +51,9 @@ ENV TZ=Asia/Jakarta EXPOSE 2200 8080 8443 LABEL org.opencontainers.image.title="Tunnel Please" \ - org.opencontainers.image.description="SSH-based tunnel server" + org.opencontainers.image.description="SSH-based tunnel server" \ + org.opencontainers.image.version="${VERSION}" \ + org.opencontainers.image.revision="${COMMIT}" \ + org.opencontainers.image.created="${BUILD_DATE}" ENTRYPOINT ["/app/tunnel_pls"] diff --git a/main.go b/main.go index 0d90318..4b5c496 100644 --- a/main.go +++ b/main.go @@ -8,14 +8,22 @@ import ( "os" "tunnel_pls/server" "tunnel_pls/utils" + "tunnel_pls/version" "golang.org/x/crypto/ssh" ) func main() { + if len(os.Args) > 1 && (os.Args[1] == "--version" || os.Args[1] == "-v") { + fmt.Println(version.GetVersion()) + os.Exit(0) + } + log.SetOutput(os.Stdout) log.SetFlags(log.LstdFlags | log.Lshortfile) + log.Printf("Starting %s", version.GetVersion()) + pprofEnabled := utils.Getenv("PPROF_ENABLED", "false") if pprofEnabled == "true" { pprofPort := utils.Getenv("PPROF_PORT", "6060") @@ -30,7 +38,7 @@ func main() { sshConfig := &ssh.ServerConfig{ NoClientAuth: true, - ServerVersion: "SSH-2.0-TunnlPls-1.0", + ServerVersion: fmt.Sprintf("SSH-2.0-TunnlPls-%s", version.GetShortVersion()), } sshKeyPath := "certs/ssh/id_rsa" diff --git a/version/version.go b/version/version.go new file mode 100644 index 0000000..4a45199 --- /dev/null +++ b/version/version.go @@ -0,0 +1,17 @@ +package version + +import "fmt" + +var ( + Version = "dev" + BuildDate = "unknown" + Commit = "unknown" +) + +func GetVersion() string { + return fmt.Sprintf("tunnel_pls %s (commit: %s, built: %s)", Version, Commit, BuildDate) +} + +func GetShortVersion() string { + return Version +}