Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# We can only ignore eventual build binary file.
# Everything that related to git, or is committed in git repository *MUST NOT* be ignored.
# In particular, `.git` repository *MUST* be preserved because we use it to detect the version, which is included in the build binary file.
# This is necessary to ensure reproductible build (of the binary inside the Docker image).
# This is necessary to ensure reproducible build (of the binary inside the Docker image).

ue-lite
2 changes: 1 addition & 1 deletion .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Install depends
run: go get .
- name: Build
run: go build -v -o ${{ steps.repo.outputs.repo }}-${{ steps.version.outputs.version }}-${{ matrix.os }}-${{ matrix.arch }}
run: go build -v -trimpath -o ${{ steps.repo.outputs.repo }}-${{ steps.version.outputs.version }}-${{ matrix.os }}-${{ matrix.arch }}
- name: Generate artifact attestation
uses: actions/attest@v4
with:
Expand Down
13 changes: 9 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
FROM golang:1.26.1 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download && go mod verify
RUN --mount=type=cache,target=/go/pkg/mod go mod download && go mod verify
COPY . .
RUN CGO_ENABLED=0 go build -o /usr/local/bin/ue-lite
# To make reproducible the `COPY --from=builder` layer reproducible, we set modification time to build timestamp
# and we will copy the directory at once to avoid /usr/local/bin being "created" instead of copied (resulting in wrong a newer modification time).
RUN --mount=type=cache,target=/root/.cache/go-build CGO_ENABLED=0 go build -trimpath -o /usr/local/bin/ue-lite && touch --no-dereference --date="@$(ue-lite --build-timestamp)" /usr/local/bin /usr/local/bin/ue-lite

FROM alpine:3.23.4
RUN apk add --no-cache iptables iproute2
COPY --from=builder /usr/local/bin/ue-lite /usr/local/bin/ue-lite
COPY --from=builder /usr/local/bin /usr/local/bin
# Even when cache is not created and logs are not written by apk-tools itself, adding some packages always updates modification time of a lot of files.
# To make this layer reprodicible, we need to reset the modification time to build timestamp.
# Some files are read-only filesystem (mounted by Docker), so we make sure to exclude them.
RUN apk add --no-cache --logfile=no iptables iproute2 && find /bin /etc /usr /lib /sbin /var -newer /usr/local/bin/ue-lite -not -path /etc/hosts -not path /etc/resolv.conf -print0 | xargs -0r touch --no-dereference --date="@$(ue-lite --build-timestamp)"
ENTRYPOINT ["ue-lite"]
CMD ["--help"]
HEALTHCHECK --interval=1m --timeout=1s --retries=3 --start-period=5s --start-interval=100ms \
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ MKDIRP = mkdir -p
.PHONY: install uninstall build clean default
default: build
build:
go build
CGO_ENABLED=0 go build -trimpath
clean:
go clean
reinstall: uninstall install
Expand Down
41 changes: 41 additions & 0 deletions internal/app/build-time/build-time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package buildtime

import (
"context"
"fmt"
"os"
"runtime/debug"
"time"

"github.com/urfave/cli/v3"
)

// Get the build time if defined, or unix epoch
func getBuildTime() time.Time {
if info, ok := debug.ReadBuildInfo(); ok {
for _, s := range info.Settings {
if s.Key == "vcs.time" {
if t, err := time.Parse(time.RFC3339, s.Value); err == nil {
return t
}
return time.UnixMicro(0)
}
}
return time.UnixMicro(0)
}
return time.UnixMicro(0)
}

// Print build time (or Unix epoch when build time is not set) and exit the program
func PrintBuildTime(ctx context.Context, cmd *cli.Command, b bool) error {
if b {
fmt.Println(getBuildTime().Unix())
os.Exit(0)
}
return nil
}
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/nextmn/logrus-formatter/logger"

"github.com/nextmn/ue-lite/internal/app"
"github.com/nextmn/ue-lite/internal/app/build-time"
"github.com/nextmn/ue-lite/internal/config"

"github.com/sirupsen/logrus"
Expand All @@ -40,6 +41,13 @@ func main() {
},
Version: version,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "build-timestamp",
Usage: "print timestamp of build creation",
Hidden: true,
Local: true,
Action: buildtime.PrintBuildTime,
},
&cli.StringFlag{
Name: "config",
TakesFile: true,
Expand Down
Loading