diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 8e5534c..44b025b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -70,17 +70,33 @@ jobs: runs-on: ubuntu-latest needs: release # Wait for binary cache to propagate steps: - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Nix + uses: cachix/install-nix-action@v31 with: - # list of Docker images to use as base name for tags - images: | - ghcr.io/${{ github.repository }} - # generate Docker tags based on the following events/attributes - tags: | - type=ref,event=branch - type=semver,pattern={{version}} + nix_path: nixpkgs=channel:nixos-unstable + + - name: Use Cachix + uses: cachix/cachix-action@v16 + with: + name: trevstack + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Set env + run: | + TAG=${{ github.event.release.tag_name }} + VERSION=${TAG#v} + + NAME="trevstack:${VERSION}" + + REPOSITORY=${{ github.repository }} + REGISTRY="ghcr.io/${REPOSITORY}" + + echo "VERSION=${VERSION}" >> $GITHUB_ENV + echo "NAME=${NAME}" >> $GITHUB_ENV + echo "REGISTRY=${REGISTRY}" >> $GITHUB_ENV - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -89,15 +105,42 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Build & Load Images + run: | + nix build .#trevstack-linux-amd64-image && ./result | docker load + nix build .#trevstack-linux-arm64-image && ./result | docker load + nix build .#trevstack-linux-arm-image && ./result | docker load - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - name: Push Images + run: | + docker image tag ${NAME}-amd64 ${REGISTRY}/${NAME}-amd64 + docker push ${REGISTRY}/${NAME}-amd64 - - name: Build and push - uses: docker/build-push-action@v6 - with: - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + docker image tag ${NAME}-arm64 ${REGISTRY}/${NAME}-arm64 + docker push ${REGISTRY}/${NAME}-arm64 + + docker image tag ${NAME}-arm ${REGISTRY}/${NAME}-arm + docker push ${REGISTRY}/${NAME}-arm + + - name: Push Manifest + run: | + docker manifest create ${REGISTRY}/${NAME} \ + ${REGISTRY}/${NAME}-amd64 \ + ${REGISTRY}/${NAME}-arm64 \ + ${REGISTRY}/${NAME}-arm + + docker manifest annotate ${REGISTRY}/${NAME} ${REGISTRY}/${NAME}-amd64 --arch amd64 + docker manifest annotate ${REGISTRY}/${NAME} ${REGISTRY}/${NAME}-arm64 --arch arm64 + docker manifest annotate ${REGISTRY}/${NAME} ${REGISTRY}/${NAME}-arm --arch arm + + docker manifest create ${REGISTRY}/trevstack:latest \ + ${REGISTRY}/${NAME}-amd64 \ + ${REGISTRY}/${NAME}-arm64 \ + ${REGISTRY}/${NAME}-arm + + docker manifest annotate ${REGISTRY}/trevstack:latest ${REGISTRY}/${NAME}-amd64 --arch amd64 + docker manifest annotate ${REGISTRY}/trevstack:latest ${REGISTRY}/${NAME}-arm64 --arch arm64 + docker manifest annotate ${REGISTRY}/trevstack:latest ${REGISTRY}/${NAME}-arm --arch arm + + docker manifest push ${REGISTRY}/${NAME} + docker manifest push ${REGISTRY}/trevstack:latest diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index e2c33ab..0000000 --- a/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -# Nix builder -FROM nixos/nix:latest AS builder - -# Copy our source and setup our working dir. -COPY . /tmp/build -WORKDIR /tmp/build - -# Build our Nix environment -RUN nix \ - --extra-experimental-features "nix-command flakes" \ - --option filter-syscalls false \ - --accept-flake-config \ - build - -# Copy the Nix store closure into a directory. The Nix store closure is the -# entire set of Nix store values that we need for our build. -RUN mkdir /tmp/nix-store-closure -RUN cp -R $(nix-store -qR result/) /tmp/nix-store-closure - -# Final image is based on scratch. We copy a bunch of Nix dependencies -# but they're fully self-contained so we don't need Nix anymore. -FROM scratch - -WORKDIR /app - -# Copy /nix/store -COPY --from=builder /tmp/nix-store-closure /nix/store -COPY --from=builder /tmp/build/result /app - -CMD ["/app/bin/trevstack"] \ No newline at end of file diff --git a/flake.lock b/flake.lock index b2a6c67..d855e13 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1746904237, - "narHash": "sha256-3e+AVBczosP5dCLQmMoMEogM57gmZ2qrVSrmq9aResQ=", + "lastModified": 1747179050, + "narHash": "sha256-qhFMmDkeJX9KJwr5H32f1r7Prs7XbQWtO0h3V0a0rFY=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d89fc19e405cb2d55ce7cc114356846a0ee5e956", + "rev": "adaa24fbf46737f3f1b5497bf64bae750f82942e", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 8933827..5609cc7 100644 --- a/flake.nix +++ b/flake.nix @@ -83,7 +83,10 @@ packages = with pkgs; [ treli.packages."${system}".default git + + # Nix nix-update + alejandra # Server go @@ -208,11 +211,8 @@ HOME=$PWD ''; }; - in - { - default = server; - } - // builtins.listToAttrs (builtins.map (x: { + + binaries = builtins.listToAttrs (builtins.map (x: { name = "${pname}-${x.GOOS}-${x.GOARCH}"; value = server.overrideAttrs { nativeBuildInputs = @@ -235,7 +235,28 @@ ''; }; }) - host-systems) + host-systems); + + images = builtins.listToAttrs (builtins.map (x: { + name = "${pname}-${x.GOOS}-${x.GOARCH}-image"; + value = pkgs.dockerTools.streamLayeredImage { + name = "${pname}"; + tag = "${version}-${x.GOARCH}"; + created = "now"; + architecture = "${x.GOARCH}"; + contents = [binaries."${pname}-${x.GOOS}-${x.GOARCH}"]; + config = { + Cmd = ["${binaries."${pname}-${x.GOOS}-${x.GOARCH}"}/bin/${pname}-${x.GOOS}-${x.GOARCH}-${version}"]; + }; + }; + }) + (builtins.filter (x: x.GOOS == "linux") host-systems)); + in + { + default = server; + } + // binaries + // images ); }; }