diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..a845fa9 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,105 @@ +name: CI/CD Pipeline + +on: + push: + branches: + - develop + tags: + - 'v*' + pull_request: + types: [opened, synchronize, reopened] + +env: + REGISTRY: labs.phundrak.com + IMAGE_NAME: phundrak/roll-one-ring + +jobs: + build-and-publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Install Nix + uses: cachix/install-nix-action@v31.5.2 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Cachix + uses: cachix/cachix-action@v16 + with: + name: roll-one-ring + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + skipPush: ${{ github.event_name == 'pull_request' }} + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Get version from Cargo.toml + id: get-version + run: | + VERSION=$(nix run .#version 2>/dev/null || echo "unknown") + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Determine tags + id: determine-tags + run: | + TAGS="" + + if [[ "${{ github.event_name }}" == "push" ]]; then + if [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then + # Push to develop branch + TAGS="${{ env.IMAGE_NAME }}:develop" + elif [[ "${{ github.ref }}" == refs/tags/* ]]; then + # Tag push + VERSION_TAG=${GITHUB_REF#refs/tags/} + # Remove 'v' prefix if present + VERSION_TAG=${VERSION_TAG#v} + TAGS="${{ env.IMAGE_NAME }}:latest,${{ env.IMAGE_NAME }}:${VERSION_TAG}" + fi + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + # Pull request + PR_NUMBER=${{ github.event.number }} + TAGS="${{ env.IMAGE_NAME }}:pr${PR_NUMBER}" + fi + + echo "tags=$TAGS" >> $GITHUB_OUTPUT + echo "Tags to build: $TAGS" + + - name: Build Docker image with Nix + run: | + echo "Building Docker image..." + nix build .#docker + + # Load the image into Docker + docker load < result + + # Get the image ID that was just loaded + IMAGE_ID=$(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}" | grep "${{ env.IMAGE_NAME }}:latest" | awk '{print $2}' | head -1) + echo "Loaded image ID: $IMAGE_ID" + echo "image_id=$IMAGE_ID" >> $GITHUB_ENV + + - name: Tag and push Docker image + run: | + TAGS="${{ steps.determine-tags.outputs.tags }}" + + if [ -n "$TAGS" ]; then + IFS=',' read -ra TAG_ARRAY <<< "$TAGS" + for tag in "${TAG_ARRAY[@]}"; do + echo "Tagging and pushing: $tag" + docker tag ${{ env.image_id }} "$tag" + docker push "$tag" + done + fi + + - name: Output image tags + run: | + echo "Built and pushed the following tags:" + echo "${{ steps.determine-tags.outputs.tags }}" diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 3fda9d9..0000000 --- a/flake.lock +++ /dev/null @@ -1,96 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1756542300, - "narHash": "sha256-tlOn88coG5fzdyqz6R93SQL5Gpq+m/DsWpekNFhqPQk=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "d7600c775f877cd87b4f5a831c28aa94137377aa", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1744536153, - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1756780571, - "narHash": "sha256-xX0B7Sgx3OQvf6anaNW0vXyYDXbchSx2mnT8rqAPbWA=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "2c18db2acc837a71146ed2d6dae27bf03e3b7a4b", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix index 8abbbe8..01a0ca5 100644 --- a/flake.nix +++ b/flake.nix @@ -17,28 +17,45 @@ cargo = rustVersion; rustc = rustVersion; }; + appName = "roll-one-ring"; + cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); + version = cargoToml.package.version; appRustBuild = rustPlatform.buildRustPackage { pname = appName; - version = "0.1.0"; + version = version; src = ./.; cargoLock.lockFile = ./Cargo.lock; }; - dockerImage = pkgs.dockerTools.buildLayeredImage { - name = appName; + + makeDockerImage = tag: pkgs.dockerTools.buildLayeredImage { + name = "phundrak/${appName}"; + inherit tag; config = { Entrypoint = ["${appRustBuild}/bin/${appName}"]; Env = [ "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ]; - Tag = "latest"; }; contents = [appRustBuild pkgs.cacert]; }; + + dockerImageLatest = makeDockerImage "latest"; + dockerImageVersioned = makeDockerImage version; + in { packages = { rustPackage = appRustBuild; - docker = dockerImage; + docker = dockerImageLatest; + docker-versioned = dockerImageVersioned; + }; + defaultPackage = dockerImageLatest; + apps = { + version = { + type = "app"; + program = "${pkgs.writeShellScript "version" '' + echo "${version}" + ''}"; + }; }; - defaultPackage = dockerImage; devShell = with pkgs; mkShell { buildInputs = [ bacon