# Steps run in file order, in one container, sharing /ci/build. # Same image as the Containerfile's build stage, so the binary links against # the glibc of the trixie runtime image. image = "docker.io/library/rust:1-trixie" work_dir = "/ci/build" clone_project_to = "/ci/build/project" shell_setup = """ set -euo pipefail export CARGO_TARGET_DIR=/ci/cache/target export ANDROID_HOME=/ci/cache/android-sdk """ timeout = 3600 memory_limit = "6g" # CARGO_TARGET_DIR must stay outside clone_project_to: the checkout is # extracted over that directory. cache = [ { path = "/ci/cache/target", max_size = "16g" }, { path = "/usr/local/cargo/registry", max_size = "4g" }, # trunk downloads wasm-opt here. { path = "/root/.cache/trunk", max_size = "1g" }, { path = "/ci/cache/android-sdk", max_size = "3g" }, { path = "/root/.gradle", max_size = "4g" }, ] [on] push = ["master"] tag = true [variables] [variables.TRUNK_VERSION] default = "0.21.14" description = "Trunk release that builds the wasm frontend. Matches the Containerfile." [[steps]] name = "setup" timeout = 900 run_sh = """ apt-get update -qq && apt-get install -y -qq --no-install-recommends \ podman-remote openjdk-21-jdk-headless > /dev/null rustup component add rustfmt clippy rustup target add wasm32-unknown-unknown url="https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz" curl -fsSL -o /tmp/trunk.tar.gz "$url" curl -fsSL "$url.sha256" | awk '{print $1 " /tmp/trunk.tar.gz"}' | sha256sum -c - tar xzf /tmp/trunk.tar.gz -C /usr/local/bin rm -f /tmp/trunk.tar.gz # Only for the license files. Gradle installs the platform and build-tools # that the app needs on its own. if [ ! -x "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]; then curl -fsSL -o /tmp/clt.zip \ "https://dl.google.com/android/repository/commandlinetools-linux-15859902_latest.zip" echo "040d3996a65543d22ec4bf73e4c37aa37a8d4af4 /tmp/clt.zip" | sha1sum -c - unzip -q /tmp/clt.zip -d /tmp/clt mkdir -p "$ANDROID_HOME/cmdline-tools" mv /tmp/clt/cmdline-tools "$ANDROID_HOME/cmdline-tools/latest" rm -r /tmp/clt /tmp/clt.zip fi (yes || true) | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null trunk --version && cargo fmt --version && cargo clippy --version && java -version """ # Reported, not gated: clippy findings change between toolchain versions. [[steps]] name = "lint" warn_on_fail = true run_sh = """ cd project cargo fmt --check cargo clippy --workspace --all-targets -- -D warnings """ [[steps]] name = "test" run_sh = "cd project && cargo test --workspace" [[steps]] name = "build" timeout = 2400 run_sh = """ cd project (cd web && trunk build --release) cargo build --locked --release -p server """ [[steps]] name = "android" timeout = 1800 run_sh = """ cd project/android ./gradlew --no-daemon testDebugUnitTest assembleDebug cp app/build/outputs/apk/debug/app-debug.apk /ci/build/opentracker-debug.apk """ publish_file = ["/ci/build/opentracker-debug.apk"] [[steps]] name = "android-lint" warn_on_fail = true run_sh = "cd project/android && ./gradlew --no-daemon lintDebug" # Packages what the build step made via the Containerfile's prebuilt stage. # Needs CI_ENGINE_SOCKET=1 on the server and the CI secret REGISTRY_PASSWORD # (admin password). Every run pushes the short sha and "edge". A tag run also # pushes the tag and "latest". [[steps]] name = "image" engine_socket = true timeout = 900 run_sh = """ cd project mkdir -p ci-bin cp "${CARGO_TARGET_DIR}/release/otserver" ci-bin/otserver cp -r web/dist ci-bin/web echo "$REGISTRY_PASSWORD" | podman-remote login "${CI_REGISTRY%%/*}" -u admin --password-stdin # A remote build sends a seccomp profile path that the server opens. The # client's default path may not exist on the server, so ask the server. prof=$(podman-remote info --format '{{.Host.Security.SECCOMPProfilePath}}' 2>/dev/null || true) if [ -n "$prof" ]; then seccomp="seccomp=$prof" else seccomp="seccomp=unconfined" fi img="$CI_REGISTRY:$CI_COMMIT_SHORT_SHA" podman-remote build --security-opt "$seccomp" \ -f Containerfile -t "$img" --build-arg BIN_STAGE=prebuilt . podman-remote push "$img" if [ -n "${CI_COMMIT_TAG:-}" ]; then tags="$CI_COMMIT_TAG latest" else tags="edge" fi for t in $tags; do podman-remote tag "$img" "$CI_REGISTRY:$t" podman-remote push "$CI_REGISTRY:$t" done """