diff --git a/.github/workflows/continuous-delivery.yml b/.github/workflows/continuous-delivery.yml index 999d5f0..f6f75c7 100644 --- a/.github/workflows/continuous-delivery.yml +++ b/.github/workflows/continuous-delivery.yml @@ -22,7 +22,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Publish binary. - run: nix develop -c make publish-binary RELEASE="${GITHUB_REF_NAME}" + run: nix develop -c just publish-binary "${GITHUB_REF_NAME}" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by GitHub Actions. @@ -35,7 +35,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Publish crate. - run: nix develop -c make publish-crate + run: nix develop -c just publish-crate env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} @@ -57,6 +57,8 @@ jobs: steps: - name: Checkout code. uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Setup Nix. + uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Login to GitHub Container Registry @@ -66,7 +68,7 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Publish Docker Image - run: make publish-docker-image RELEASE="${GITHUB_REF_NAME}" PLATFORM="${{ matrix.platform }}" TARGET="${{ matrix.target }}" SUFFIX="${{ matrix.suffix }}" + run: nix develop -c just publish-docker-image "${GITHUB_REF_NAME}" "${{ matrix.platform }}" "${{ matrix.target }}" "${{ matrix.suffix }}" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -77,6 +79,8 @@ jobs: steps: - name: Checkout code. uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Setup Nix. + uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Login to GitHub Container Registry @@ -86,4 +90,4 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Publish Docker Manifest - run: make publish-docker-manifest RELEASE="${GITHUB_REF_NAME}" + run: nix develop -c just publish-docker-manifest "${GITHUB_REF_NAME}" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index bda7987..225bdbb 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -16,8 +16,10 @@ jobs: steps: - name: Checkout code. uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Setup Nix. + uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Check permissions. - run: make check-${{ matrix.language }}-permissions + run: nix develop -c just check-${{ matrix.language }}-permissions formatting: name: Formatting @@ -32,7 +34,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Check formatting. - run: nix develop -c make check-${{ matrix.language }}-formatting + run: nix develop -c just check-${{ matrix.language }}-formatting linting: name: Linting @@ -47,7 +49,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Check linting. - run: nix develop -c make check-${{ matrix.language }}-linting + run: nix develop -c just check-${{ matrix.language }}-linting dependencies: name: Dependencies @@ -62,7 +64,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Check dependencies. - run: nix develop -c make check-${{ matrix.language }}-dependencies + run: nix develop -c just check-${{ matrix.language }}-dependencies compile: name: Compile @@ -76,7 +78,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Compile. - run: nix develop -c make compile + run: nix develop -c just compile unit-test: name: Unit Test @@ -90,7 +92,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Unit test. - run: nix develop -c make unit-test + run: nix develop -c just unit-test end-to-end-test: name: End to End Test @@ -104,4 +106,4 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: End to End test. - run: nix develop -c make end-to-end-test + run: nix develop -c just end-to-end-test diff --git a/.github/workflows/dogfood.yml b/.github/workflows/dogfood.yml index 707f9ae..e861c2c 100644 --- a/.github/workflows/dogfood.yml +++ b/.github/workflows/dogfood.yml @@ -21,4 +21,4 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31.9.0 - name: Dogfooding Docker. - run: nix develop -c make dogfood-docker FROM="origin/${{ github.base_ref }}" + run: nix develop -c just dogfood-docker "origin/${{ github.base_ref }}" diff --git a/.github/workflows/github-actions-workflows.yml b/.github/workflows/github-actions-workflows.yml index 29773e7..2da3832 100644 --- a/.github/workflows/github-actions-workflows.yml +++ b/.github/workflows/github-actions-workflows.yml @@ -18,7 +18,7 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Check formatting. - run: nix develop -c make check-yaml-formatting + run: nix develop -c just check-yaml-formatting linting: name: Linting @@ -32,4 +32,4 @@ jobs: - name: Setup Nix. uses: cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0 - name: Check GitHub Actions workflows linting. - run: nix develop -c make check-github-actions-workflows-linting + run: nix develop -c just check-github-actions-workflows-linting diff --git a/Makefile b/Makefile deleted file mode 100644 index ec337c0..0000000 --- a/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -# Auto-detect musl target for static binaries (Linux only) -# Only set MUSL_TARGET on supported architectures; targets that need it will check -MUSL_TARGET := $(shell uname -m | sed 's/^x86_64$$/x86_64-unknown-linux-musl/;s/^aarch64$$/aarch64-unknown-linux-musl/') - -define check-musl-target -$(if $(filter %unknown-linux-musl,$(MUSL_TARGET)),,$(error Unsupported architecture: $(shell uname -m). Static musl builds only supported on Linux x86_64 and aarch64)) -endef - -# Use --locked in CI to ensure reproducible builds -CARGO_LOCKED := $(if $(CI),--locked,) - -.PHONY: default -default: compile - -.PHONY: check-shell-permissions -check-shell-permissions: - ./ci/check-scripts-permissions.sh - -.PHONY: check-rust-formatting -check-rust-formatting: - cargo fmt --all -- --check --config=group_imports=StdExternalCrate - -.PHONY: fix-rust-formatting -fix-rust-formatting: - cargo fmt --all -- --config=group_imports=StdExternalCrate - -.PHONY: check-shell-formatting -check-shell-formatting: - shfmt --simplify --diff ci/* - -.PHONY: fix-shell-formatting -fix-shell-formatting: - shfmt --simplify --write ci/* - -.PHONY: check-python-formatting -check-python-formatting: - autopep8 --exit-code --diff --aggressive --aggressive --max-line-length 120 --recursive end-to-end-tests/ - -.PHONY: fix-python-formatting -fix-python-formatting: - autopep8 --in-place --aggressive --aggressive --max-line-length 120 --recursive end-to-end-tests/ - -.PHONY: check-yaml-formatting -check-yaml-formatting: - yamlfmt -verbose -lint -dstar .github/workflows/* - -.PHONY: fix-yaml-formatting -fix-yaml-formatting: - yamlfmt -verbose -dstar .github/workflows/* - -.PHONY: check-rust-linting -check-rust-linting: - cargo clippy --verbose $(CARGO_LOCKED) -- -D warnings - -.PHONY: check-shell-linting -check-shell-linting: - shellcheck ci/*.sh - -.PHONY: check-python-linting -check-python-linting: - ruff check --line-length 120 end-to-end-tests/ - -.PHONY: fix-python-linting -fix-python-linting: - ruff check --fix --line-length 120 end-to-end-tests/ - -.PHONY: check-github-actions-workflows-linting -check-github-actions-workflows-linting: - actionlint -verbose -color - -.PHONY: check-rust-dependencies -check-rust-dependencies: - cargo machete - -.PHONY: compile -compile: - cargo build --verbose $(CARGO_LOCKED) - -.PHONY: unit-test -unit-test: - cargo test --verbose $(CARGO_LOCKED) - -.PHONY: end-to-end-test -end-to-end-test: compile - cd end-to-end-tests/ && behave - -.PHONY: release -release: - $(call check-musl-target) - cargo build --release --target=$(MUSL_TARGET) --locked --verbose - -.PHONY: publish-binary -publish-binary: release - ./ci/publish-binary.sh ${RELEASE} $(MUSL_TARGET) - -.PHONY: publish-crate -publish-crate: - cargo publish --verbose - -# Emulate GitHub Actions CI environment for testing -GITHUB_ACTIONS_ENV := --env HOME=/github/home --env GITHUB_ACTIONS=true --env CI=true - -.PHONY: dogfood-docker -dogfood-docker: release - docker build --build-arg TARGET=$(MUSL_TARGET) --tag clean_git_history --file Dockerfile . - docker run --rm --volume $(PWD):/workspace --workdir /workspace $(GITHUB_ACTIONS_ENV) clean_git_history --verbose $(FROM) - -.PHONY: publish-docker-image -publish-docker-image: - ./ci/publish-docker-image.sh ${RELEASE} ${PLATFORM} ${TARGET} ${SUFFIX} - -.PHONY: publish-docker-manifest -publish-docker-manifest: - ./ci/publish-docker-manifest.sh ${RELEASE} diff --git a/flake.nix b/flake.nix index 5140649..5dd3fc3 100644 --- a/flake.nix +++ b/flake.nix @@ -38,6 +38,8 @@ hardeningDisable = [ "all" ]; buildInputs = [ + # Task runner. + pkgs.just # Rust with cross-compilation targets built-in. rustWithTargets # Shell formatting. diff --git a/justfile b/justfile new file mode 100644 index 0000000..e6f227e --- /dev/null +++ b/justfile @@ -0,0 +1,89 @@ +# Auto-detect musl target for static binaries. +# Only set MUSL_TARGET on supported architectures; targets that need it will check. +MUSL_TARGET := `case "$(uname -m)" in x86_64) printf '%s' x86_64-unknown-linux-musl ;; aarch64) printf '%s' aarch64-unknown-linux-musl ;; *) printf '%s' '' ;; esac` + +# Use --locked in CI to ensure reproducible builds. +CARGO_LOCKED := if env("CI", "") != "" { "--locked" } else { "" } + +default: compile + +check-shell-permissions: + ./ci/check-scripts-permissions.sh + +check-rust-formatting: + cargo fmt --all -- --check --config=group_imports=StdExternalCrate + +fix-rust-formatting: + cargo fmt --all -- --config=group_imports=StdExternalCrate + +check-shell-formatting: + shfmt --simplify --diff ci/* + +fix-shell-formatting: + shfmt --simplify --write ci/* + +check-python-formatting: + autopep8 --exit-code --diff --aggressive --aggressive --max-line-length 120 --recursive end-to-end-tests/ + +fix-python-formatting: + autopep8 --in-place --aggressive --aggressive --max-line-length 120 --recursive end-to-end-tests/ + +check-yaml-formatting: + yamlfmt -verbose -lint -dstar .github/workflows/* + +fix-yaml-formatting: + yamlfmt -verbose -dstar .github/workflows/* + +check-rust-linting: + cargo clippy --verbose {{ CARGO_LOCKED }} -- -D warnings + +check-shell-linting: + shellcheck ci/*.sh + +check-python-linting: + ruff check --line-length 120 end-to-end-tests/ + +fix-python-linting: + ruff check --fix --line-length 120 end-to-end-tests/ + +check-github-actions-workflows-linting: + actionlint -verbose -color + +check-rust-dependencies: + cargo machete + +compile: + cargo build --verbose {{ CARGO_LOCKED }} + +unit-test: + cargo test --verbose {{ CARGO_LOCKED }} + +end-to-end-test: compile + cd end-to-end-tests/ && behave + +release: + test -n "{{ MUSL_TARGET }}" || (printf '%s\n' "Unsupported architecture: $(uname -m)." >&2; exit 1) + cargo build --release --target={{ MUSL_TARGET }} --locked --verbose + +publish-binary RELEASE: release + ./ci/publish-binary.sh {{ RELEASE }} {{ MUSL_TARGET }} + +publish-crate: + cargo publish --verbose + +dogfood-docker FROM: release + docker build --build-arg TARGET={{ MUSL_TARGET }} --tag clean_git_history --file Dockerfile . + # Emulate GitHub Actions CI environment via environment variables for testing. + docker run --rm \ + --volume {{ justfile_directory() }}:/workspace \ + --workdir /workspace \ + --env HOME=/github/home \ + --env GITHUB_ACTIONS=true \ + --env CI=true \ + clean_git_history --verbose {{ FROM }} + +publish-docker-image RELEASE PLATFORM TARGET SUFFIX: + ./ci/publish-docker-image.sh {{ RELEASE }} {{ PLATFORM }} {{ TARGET }} {{ SUFFIX }} + +publish-docker-manifest RELEASE: + ./ci/publish-docker-manifest.sh {{ RELEASE }}