diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index be104af..f73e34f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,92 +16,90 @@ env: jobs: - docker: + publish-nix-container: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - platform: - - linux/amd64 - - linux/arm/v6 - - linux/arm/v7 - - linux/arm64 + system: + - aarch64-linux + - x86_64-linux steps: - - name: Checkout - uses: actions/checkout@v3 + - uses: actions/checkout@v3 - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - uses: actions/setup-go@v4 + - name: Login to GitHub Container Registry + uses: docker/login-action@v2.2.0 with: - go-version-file: 'go.mod' - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - driver-opts: | - image=moby/buildkit:v0.10.6 - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} + registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 + - uses: cachix/install-nix-action@v29 with: - # list of Docker images to use as base name for tags - images: ${{ env.REGISTRY_IMAGE }} - tags: | - type=sha,enable=false + github_access_token: ${{ secrets.GITHUB_TOKEN }} + extra_nix_config: | + extra-platforms = ${{ matrix.system }} - - name: Build and push (by digest) - uses: docker/build-push-action@v4 - id: build - with: - push: true - context: . - file: docker/slim.Dockerfile - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ matrix.platform }} - outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true - cache-from: type=gha - cache-to: type=gha,mode=max - - name: Export digest + - uses: DeterminateSystems/magic-nix-cache-action@main + + - uses: docker/setup-qemu-action@v1 + + # build in parallel + - run: nix build .#packages.${{ matrix.system }}.leng-container-image -L + + - name: Tag and push image run: | + git_sha=$(git rev-parse --short "$GITHUB_SHA") + label=$git_sha-${{ matrix.system }} + + docker load < result + docker tag leng:nix ${{ env.REGISTRY_IMAGE }}:$label + docker push ${{ env.REGISTRY_IMAGE }}:$label + + # export digest + docker pull ${{ env.REGISTRY_IMAGE }}:$label + full=$(docker image inspect ${{ env.REGISTRY_IMAGE }}:$label --format "{{index .RepoDigests 0}}") + digest=${full#${{ env.REGISTRY_IMAGE }}@} mkdir -p /tmp/digests - digest="${{ steps.build.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" - - name: Upload digest - uses: actions/upload-artifact@v4 - with: - name: digests - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 merge-docker: runs-on: ubuntu-latest - needs: [docker] + needs: [ publish-nix-container ] steps: - - name: Download digests - uses: actions/download-artifact@v4 + - name: Login to GitHub Container Registry + uses: docker/login-action@v2.2.0 with: - name: digests - path: /tmp/digests + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: digest for x86 + run: | + system=x86_64-linux + git_sha=${GITHUB_SHA::7} + label="${git_sha}-${system}" + + # export digest x86 + docker pull ${{ env.REGISTRY_IMAGE }}:$label + full=$(docker image inspect ${{ env.REGISTRY_IMAGE }}:$label --format "{{index .RepoDigests 0}}") + digest=${full#${{ env.REGISTRY_IMAGE }}@} + mkdir -p /tmp/digests + touch "/tmp/digests/${digest#sha256:}" + + - name: digest for aarch64 + run: | + system=aarch64-linux + git_sha=${GITHUB_SHA::7} + label="${git_sha}-${system}" + + # export digest x86 + docker pull ${{ env.REGISTRY_IMAGE }}:$label + full=$(docker image inspect ${{ env.REGISTRY_IMAGE }}:$label --format "{{index .RepoDigests 0}}") + digest=${full#${{ env.REGISTRY_IMAGE }}@} + mkdir -p /tmp/digests + touch "/tmp/digests/${digest#sha256:}" - name: Docker meta id: meta @@ -110,19 +108,14 @@ jobs: # list of Docker images to use as base name for tags images: ${{ env.REGISTRY_IMAGE }} tags: | - type=schedule - # tag event - type=ref,event=tag - type=sha,event=tag - # pull request event - type=sha,event=pr - + type=sha,event=push - name: Create manifest list and push working-directory: /tmp/digests run: | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) + - name: Inspect image run: | docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} diff --git a/config.go b/config.go index be36c5d..14e2d82 100644 --- a/config.go +++ b/config.go @@ -14,10 +14,10 @@ import ( ) // BuildVersion returns the build version of leng, this should be incremented every new release -var BuildVersion = "1.5.3" +var BuildVersion = "1.6.0" // ConfigVersion returns the version of leng, this should be incremented every time the config changes so leng presents a warning -var ConfigVersion = "1.5.3" +var ConfigVersion = "1.6.0" // Config holds the configuration parameters type Config struct { diff --git a/doc/src/Nix.md b/doc/src/Nix.md index 9fc6e97..a3ce355 100644 --- a/doc/src/Nix.md +++ b/doc/src/Nix.md @@ -18,7 +18,7 @@ Please refer to [Configuration](./Configuration.md) for the options you can use { inputs = { # pinned version for safety - leng.url = "github:cottand/leng/v1.5.3"; + leng.url = "github:cottand/leng/v1.6.0"; leng.nixpkgs.follows = "nixpkgs"; }; @@ -52,7 +52,7 @@ Add the following inside your configuration.nix: {pkgs, lib, ... }: { imports = [ # import leng module - (builtins.getFlake "github:cottand/leng/v1.5.3").nixosModules.default + (builtins.getFlake "github:cottand/leng/v1.6.0").nixosModules.default ]; # now you can use services.leng! diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile deleted file mode 100644 index b7f39bc..0000000 --- a/docker/alpine.Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM alpine:3.17 as certs -RUN apk --update add ca-certificates - -FROM golang:1.21.0-alpine3.17 AS builder -RUN apk add git bash gcc musl-dev upx git -WORKDIR /app -COPY . . -RUN go mod tidy -RUN go test -v ./... -ENV CGO_ENABLED=0 -RUN go build -ldflags "-w -s" -v -o main -RUN upx -9 -o main.minify main && mv main.minify main - -FROM scratch -COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY --from=builder /app/main /usr/bin/main - -ENTRYPOINT ["/usr/bin/main"] \ No newline at end of file diff --git a/docker/slim.Dockerfile b/docker/slim.Dockerfile deleted file mode 100644 index c460b83..0000000 --- a/docker/slim.Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM alpine:3.17 as certs -RUN apk --update add ca-certificates - -FROM golang:1.21.0-alpine3.17 AS builder - -RUN apk add git bash gcc musl-dev upx git -WORKDIR /app -COPY . . -RUN --mount=type=cache,target=/go/pkg/mod/ \ - go mod tidy -#RUN go test -v ./... -ENV CGO_ENABLED=0 -RUN --mount=type=cache,target=/go/pkg/mod/ \ - go build -ldflags "-w -s" -v -o main -RUN upx -9 -o main.minify main && mv main.minify main - -FROM alpine:3.17 -COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY --from=builder /app/main /usr/bin/main - -ENTRYPOINT ["/usr/bin/main"] \ No newline at end of file diff --git a/flake.nix b/flake.nix index 22c02a3..ba33034 100644 --- a/flake.nix +++ b/flake.nix @@ -12,12 +12,31 @@ # Build & packaging ## use with `nix build` packages = rec { - leng = pkgs.buildGo122Module { + leng = pkgs.buildGoModule { inherit system; vendorHash = null; pname = "leng"; - version = "1.5.3"; + version = "1.6.0"; src = nixpkgs.lib.sources.cleanSource ./.; + ldflags = [ "-s -w" ]; + CGO_ENABLED = "0"; + # upx does not support darwin + postInstall = if pkgs.lib.strings.hasSuffix "darwin" system then "" else '' + cd $out/bin + ${pkgs.upx}/bin/upx -9 -o leng.mini leng + rm leng + mv leng.mini leng + ''; + }; + leng-container-image = pkgs.dockerTools.buildImage { + name = "leng"; + created = "now"; + tag = "nix"; + copyToRoot = pkgs.buildEnv { + name = "files"; + paths = [ leng pkgs.cacert ]; + }; + config.Entrypoint = [ "${leng}/bin/leng" ]; }; default = leng; }; @@ -28,7 +47,7 @@ devShells = rec { # main development shell leng = with pkgs; mkShell { - packages = [ fish go_1_21 mdbook ]; + packages = [ fish go mdbook ]; # Note that `shellHook` still uses bash syntax. This starts fish, then exists the bash shell when fish exits. shellHook = "fish && exit"; }; @@ -98,7 +117,7 @@ ## implementation config = mkIf cfg.enable { environment = { - etc."leng.toml".source = { blocking.sourcesStore = "/var/lib/leng-sources";} // (toml.generate "leng.toml" cfg.configuration); + etc."leng.toml".source = { blocking.sourcesStore = "/var/lib/leng-sources"; } // (toml.generate "leng.toml" cfg.configuration); systemPackages = [ cfg.package ]; }; diff --git a/logger.go b/logger.go index 39d08dc..f5527cb 100644 --- a/logger.go +++ b/logger.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "os" + "path/filepath" "regexp" "strconv" "strings" @@ -95,6 +96,7 @@ func parseLogConfig(logConfigString string) (*logConfig, error) { } func createLogFile(fileName string) (*os.File, error) { + fileName = filepath.Clean(fileName) if _, err := os.Stat(fileName); os.IsNotExist(err) { if _, err := os.Create(fileName); err != nil { return nil, fmt.Errorf("error creating log file '%s': %s", fileName, err)