diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d7847f1..0943a58 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,54 +1,59 @@ -name: CI +name: CI/CD on: + workflow_call: push: branches: - main pull_request: workflow_dispatch: -jobs: - fmt: - name: Check Formatting - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - name: Cache cargo dependencies - uses: Swatinem/rust-cache@v2 +env: + CI_IS_DEFAULT_BRANCH: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + CI_IS_TAG: ${{ startsWith(github.ref, 'refs/tags/') }} - - name: Check formatting - run: cargo fmt --check --all +# https://stackoverflow.com/a/72408109 +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true - check: - name: Lint and Build - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - name: Cache cargo dependencies - uses: Swatinem/rust-cache@v2 - - - name: Clippy lints - run: cargo clippy --all --all-features --all-targets --no-deps -- -D warnings - - - name: Cargo Doc - run: RUSTDOCFLAGS="-D warnings" cargo doc --all --all-features --no-deps --document-private-items - - test: - name: Run Tests on all platforms - strategy: - matrix: - runs-on: ["ubuntu-24.04", "windows-2022", "macos-14"] - runs-on: ${{ matrix.runs-on }} - steps: - - uses: actions/checkout@v4 - - name: Cache cargo dependencies - uses: Swatinem/rust-cache@v2 - - - name: Test - run: cargo test --all --all-features --all-targets +jobs: + check-inputs: + runs-on: ubuntu-24.04 + outputs: + cargo-profile: ${{ steps.set-profile.outputs.CI_CARGO_PROFILE }} + is-default-branch: ${{ steps.set-is-default-branch.outputs.CI_IS_DEFAULT_BRANCH == 'true' }} - deny: - name: Run cargo deny - runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 - - uses: EmbarkStudios/cargo-deny-action@v1 + - name: Set cargo-profile + id: set-cargo-profile + run: | + if [[ ${CI_IS_DEFAULT_BRANCH} == 'true' ]]; then + CI_CARGO_PROFILE="artifact" + else + CI_CARGO_PROFILE="artifact-dev" + fi + echo "CI_CARGO_PROFILE=${CI_CARGO_PROFILE}" >> $GITHUB_OUTPUT + echo "CI_CARGO_PROFILE=${CI_CARGO_PROFILE}" + + - name: Set is-default-branch + id: set-is-default-branch + run: | + CI_IS_DEFAULT_BRANCH="${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}" + echo "CI_IS_DEFAULT_BRANCH=${CI_IS_DEFAULT_BRANCH}" >> $GITHUB_OUTPUT + echo "CI_IS_DEFAULT_BRANCH=${CI_IS_DEFAULT_BRANCH}" + + + + rust: + needs: check-inputs + uses: ./.github/workflows/rust.yaml + with: + cargo-profile: ${{ needs.check-inputs.outputs.cargo-profile }} + + container: + needs: [rust, check-inputs] + uses: ./.github/workflows/container.yaml + with: + push: ${{ needs.check-inputs.outputs.is-default-branch }} + additional-tags: ${{ needs.check-inputs.outputs.is-default-branch && 'latest' || '' }} + diff --git a/.github/workflows/container.yaml b/.github/workflows/container.yaml new file mode 100644 index 0000000..3e3e596 --- /dev/null +++ b/.github/workflows/container.yaml @@ -0,0 +1,49 @@ +name: Build Containers +on: + workflow_call: + inputs: + additional-tags: + type: string + push: + required: true + type: boolean + +jobs: + build: + name: Build Container + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4.2.0 + - name: Download Rust Artifacts + uses: actions/download-artifact@v4.1.8 + with: + name: rust + path: artifacts + + - name: Build Image + id: build-image + uses: redhat-actions/buildah-build@v2.13 + with: + image: identity-server + tags: commit-${{ github.sha }} ${{ inputs.additional-tags }} + oci: true + containerfiles: | + ./identity-server/Dockerfile + + - name: Get registry url + run: | + # Container registries don't support upper case letters + CI_REGISTRY_URL="ghcr.io/${GITHUB_REPOSITORY_OWNER@L}" + echo "CI_REGISTRY_URL=${CI_REGISTRY_URL}" >> "${GITHUB_ENV}" + echo "CI_REGISTRY_URL=${CI_REGISTRY_URL}" + + - name: Push To Github Packages + if: ${{ inputs.push }} + uses: redhat-actions/push-to-registry@v2.8 + with: + image: ${{ steps.build-image.outputs.image }} + tags: ${{ steps.build-image.outputs.tags }} + registry: ${{ env.CI_REGISTRY_URL }} + username: ${{ github.actor }} + password: ${{ github.token }} + extra-args: --disable-content-trust diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 4d34528..0000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,102 +0,0 @@ -name: Release -on: - workflow_dispatch: - inputs: - component: - description: "The component to release" - required: true - type: choice - options: - - identity-server - -jobs: - build: - name: Build the code for each platform - # unless we use osxcross, we can only target mac from a mac machine - runs-on: macos-14 - env: - LINUX: x86_64-unknown-linux-musl - LINUX_ARM: aarch64-unknown-linux-musl - WINDOWS: x86_64-pc-windows-gnu - MACOS: aarch64-apple-darwin - steps: - - uses: actions/checkout@v4.2.0 - - uses: mlugg/setup-zig@v1.2.1 - with: - version: 0.13.0 - - name: Cache cargo dependencies - uses: Swatinem/rust-cache@v2.7.3 - # - name: Install mingw - # run: sudo apt-get install -y mingw-w64 - - - name: Install cargo-zigbuild - run: cargo install --locked cargo-zigbuild@0.19.3 - - - name: Cargo zigbuild - run: | - cargo zigbuild \ - --target ${LINUX} \ - --target ${LINUX_ARM} \ - --target ${WINDOWS} \ - --target ${MACOS} \ - --profile artifact \ - -p ${{ inputs.component }} - - name: Arrange artifact directory - run: | - set -Eeuxo pipefail - mkdir artifacts - component="${{ inputs.component }}" - for f in target/*/artifact/"${component}"{,\.exe}; do - target_triple="$(echo "${f}" | cut -d '/' -f2)" - case "${target_triple}" in - "${LINUX}") - mv "${f}" "artifacts/${component}-linux-x86_64" ;; - "${LINUX_ARM}") - mv "${f}" "artifacts/${component}-linux-aarch64" ;; - "${WINDOWS}") - mv "${f}" "artifacts/${component}-windows-x86_64.exe" ;; - "${MACOS}") - mv "${f}" "artifacts/${component}-macos-aarch64" ;; - *) - echo "Unexpected target triple" - exit 1 ;; - esac - done - - ls -aRsh artifacts - - - name: Compute sha256 checksums - run: | - set -Eeuxo pipefail - pushd artifacts - for f in *; do - shasum -a 256 "${f}" > "${f}.sha256" - done - ls -aRsh - popd - - - name: Upload artifacts - uses: actions/upload-artifact@v4.4.0 - with: - name: rust - if-no-files-found: error - retention-days: 30 - path: | - artifacts - - release: - name: Create Release and Tag - runs-on: ubuntu-24.04 - needs: build - steps: - - name: Download Rust Artifacts - uses: actions/download-artifact@v4.1.8 - with: - # didn't specify artifact name, so all artifacts are downloaded and merged - # into the `artifacts` dir - path: artifacts - merge-multiple: true - - - name: List Downloaded Artifacts - run: ls -aRsh artifacts - diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml new file mode 100644 index 0000000..7c76e91 --- /dev/null +++ b/.github/workflows/rust.yaml @@ -0,0 +1,182 @@ +name: Rust CI +on: + workflow_call: + inputs: + cargo-profile: + required: true + type: string + +env: + CI_IS_DEFAULT_BRANCH: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + +jobs: + fmt: + name: Check Formatting + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4.2.0 + - name: Check formatting + run: cargo fmt --check --all + + lint: + name: Lints + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4.2.0 + - name: Cache cargo dependencies + uses: Swatinem/rust-cache@v2.7.3 + with: + save-if: ${{ env.CI_IS_DEFAULT_BRANCH }} + + - name: Clippy lints + run: cargo clippy --profile artifact-dev --all --all-features --all-targets --no-deps -- -D warnings + + - name: Cargo Doc + run: RUSTDOCFLAGS="-D warnings" cargo doc --profile artifact-dev --all --all-features --no-deps --document-private-items + + test: + name: Run Tests + strategy: + matrix: + runs-on: ["ubuntu-24.04", "windows-2022", "macos-14"] + runs-on: ${{ matrix.runs-on }} + steps: + - uses: actions/checkout@v4.2.0 + - name: Cache cargo dependencies + uses: Swatinem/rust-cache@v2.7.3 + with: + save-if: ${{ env.CI_IS_DEFAULT_BRANCH }} + + - name: Test + run: cargo test --profile artifact-dev --all --all-features --all-targets + + deny: + name: Licensing and Advisories + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4.2.0 + - uses: EmbarkStudios/cargo-deny-action@v2.0.1 + + build: + name: Build Binaries + env: + LINUX: x86_64-unknown-linux-musl + LINUX_ARM: aarch64-unknown-linux-musl + WINDOWS: x86_64-pc-windows-gnu + MACOS: aarch64-apple-darwin + # We run the jobs with a matrix, because currently we don't support cross + # compilation to macos unless your'e already on macos. And mac runners are + # expensive, so we choose to only run the builds for targets on the mac runners. + strategy: + matrix: + runner-vars: + - runs-on: macos-14 + host-triple: aarch64-apple-darwin + artifact-name: rust-macos + - runs-on: ubuntu-24.04 + host-triple: x86_64-unknown-linux-musl + artifact-name: rust-linux + runs-on: ${{ matrix.runner-vars.runs-on }} + steps: + - uses: actions/checkout@v4.2.0 + - uses: mlugg/setup-zig@v1.2.1 + with: + version: 0.13.0 + - name: Cache cargo dependencies + uses: Swatinem/rust-cache@v2.7.3 + with: + save-if: ${{ env.CI_IS_DEFAULT_BRANCH }} + + - name: Install cargo-zigbuild + run: cargo install --locked cargo-zigbuild@0.19.3 + + - name: | + Configure cross compilation targets for runner + ${{ matrix.runner-vars.runs-on }} (${{ matrix.runner-vars.host-triple }}) + run: | + case "${{ matrix.runner-vars.host-triple }}" in + "${LINUX}" | "${LINUX_ARM}") + target_array=("${LINUX}" "${LINUX_ARM}" "${WINDOWS}") ;; + "${MACOS}") + target_array=("${MACOS}") ;; + *) + echo "Unexpected value for host triple" + exit 1 ;; + esac + CI_CARGO_TARGETS="" + for t in "${target_array[@]}"; do + CI_CARGO_TARGETS+="--target ${t} " + done + echo "CI_CARGO_TARGETS=${CI_CARGO_TARGETS}" >> $GITHUB_ENV + echo "CI_CARGO_TARGETS=${CI_CARGO_TARGETS}" + + - name: Cargo zigbuild + run: | + cargo zigbuild \ + ${CI_CARGO_TARGETS} \ + --profile ${{ inputs.cargo-profile }} \ + --all + + - name: Arrange artifact directory + run: | + set -Eeuxo pipefail + mkdir artifacts + # TODO: Make it possible to release *all* binaries in these artifacts, not + # just the identity-server. + component="identity-server" + if [[ "${{ inputs.cargo-profile }}" == "dev" ]]; then + profile_dir="debug" + else + profile_dir="${{ inputs.cargo-profile }}" + fi + shopt -s nullglob #https://unix.stackexchange.com/a/293650 + for f in target/*/"${profile_dir}"/"${component}"{,\.exe}; do + target_triple="$(echo "${f}" | cut -d '/' -f2)" + case "${target_triple}" in + "${LINUX}") + mv "${f}" "artifacts/${component}-linux-x86_64" ;; + "${LINUX_ARM}") + mv "${f}" "artifacts/${component}-linux-aarch64" ;; + "${WINDOWS}") + mv "${f}" "artifacts/${component}-windows-x86_64.exe" ;; + "${MACOS}") + mv "${f}" "artifacts/${component}-macos-aarch64" ;; + *) + echo "Unexpected target triple" + exit 1 ;; + esac + done + ls -aRsh artifacts + + - name: Compute sha256 checksums + run: | + set -Eeuxo pipefail + pushd artifacts + for f in *; do + shasum -a 256 "${f}" > "${f}.sha256" + done + ls -aRsh + popd + + - name: Upload artifacts + uses: actions/upload-artifact@v4.4.0 + with: + name: ${{ matrix.runner-vars.artifact-name }} + if-no-files-found: error + retention-days: 1 + path: | + artifacts + + merge: + name: Merge Artifacts + runs-on: ubuntu-24.04 + needs: build + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@v4.4.0 + with: + name: rust + compression-level: 9 + delete-merged: true + pattern: rust-* + diff --git a/Cargo.toml b/Cargo.toml index 3782c2e..1141dcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,14 +56,19 @@ default-features = false # Enable a small amount of optimization in debug mode opt-level = 1 -# Enable high optimizations for dependencies, but not for our code: [profile.dev.package."*"] -# Seems to cause crashes on mac on opt-level 3 +# Enable high optimizations for dependencies, but not for our code: opt-level = 2 -# What we use when producing artifacts to distribute +# What we use when producing artifacts to distribute, size matters more than speed [profile.artifact] inherits = "release" lto = true strip = true debug = false + +# What we use when producing artifacts in PRs, speed matters more than size +[profile.artifact-dev] +inherits = "dev" +strip = true +debug = false