Skip to content

Bump actions/checkout from 6.0.2 to 7.0.1 (#52) #129

Bump actions/checkout from 6.0.2 to 7.0.1 (#52)

Bump actions/checkout from 6.0.2 to 7.0.1 (#52) #129

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
# Cancel superseded runs on the same ref.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
# Detect which areas changed so jobs only run when relevant. Rust jobs run on
# core/** changes; the iOS job runs on Swift, test, Tuist, script, or binding
# (core/**) changes. A workflow edit runs everything. Docs-only changes skip
# every job.
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
rust: ${{ steps.filter.outputs.rust }}
swift: ${{ steps.filter.outputs.swift }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- id: filter
env:
EVENT: ${{ github.event_name }}
BASE_REF: ${{ github.base_ref }}
BEFORE: ${{ github.event.before }}
SHA: ${{ github.sha }}
run: |
set -euo pipefail
if [[ "$EVENT" == "pull_request" ]]; then
git fetch --no-tags origin "$BASE_REF"
RANGE="origin/$BASE_REF...HEAD"
else
RANGE="$BEFORE...$SHA"
fi
FILES=$(git diff --name-only "$RANGE" 2>/dev/null || git diff --name-only HEAD~1)
echo "Changed files:"; echo "$FILES"
rust=false; swift=false
if grep -qE '^(core/|\.github/workflows/ci\.yml)' <<<"$FILES"; then rust=true; fi
if grep -qE '^(App/|Modules/|UITests/|Tuist/|scripts/|core/|Project\.swift|Tuist\.swift|\.github/workflows/ci\.yml)' <<<"$FILES"; then swift=true; fi
echo "rust=$rust" | tee -a "$GITHUB_OUTPUT"
echo "swift=$swift" | tee -a "$GITHUB_OUTPUT"
rust:
name: Rust core
runs-on: macos-26
needs: changes
if: needs.changes.outputs.rust == 'true'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
with:
components: rustfmt, clippy
- name: Cache cargo registry and target
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: core
- name: rustfmt --check
working-directory: core
run: cargo fmt --all -- --check
- name: clippy
working-directory: core
run: cargo clippy --all-targets -- -D warnings
- name: cargo test
working-directory: core
run: cargo test
# The relay-index feature is off by default (so the iOS staticlib never
# pulls in rusqlite), which means the default clippy/test steps above never
# compile the index modules. Lint and test them explicitly under the feature.
- name: clippy (relay-index feature)
working-directory: core
run: cargo clippy --all-targets --features relay-index -- -D warnings
- name: cargo test (relay-index feature)
working-directory: core
run: cargo test --features relay-index
cargo-deny:
name: cargo-deny
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.rust == 'true'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1
with:
manifest-path: core/Cargo.toml
command: check advisories bans
ios:
name: iOS app + tests
runs-on: macos-26
needs: changes
if: needs.changes.outputs.swift == 'true'
# Backstop against a hung simulator launch stalling the job for the 6h default.
timeout-minutes: 40
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Show Xcode version
run: xcodebuild -version
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
with:
targets: aarch64-apple-ios,aarch64-apple-ios-sim
- name: Cache cargo registry and target
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: core
# The XCFramework + UniFFI bindings are derived purely from core/. Cache
# them keyed on the Rust sources so iOS-only changes skip the Rust rebuild.
- name: Cache XCFramework + bindings
id: xcframework
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
Modules/CosignCore/Frameworks/CosignCore.xcframework
Modules/CosignCore/Sources/Generated
# Key on the Rust LIBRARY only: the top-level core/src/*.rs sources + the .udl,
# NOT core/src/bin/** (the relay binary). The XCFramework is built from the
# cosign_core library and does not depend on the relay binary, so relay-only
# edits must not invalidate this cache (they used to, via a core/src/** glob,
# forcing an ~18 min rebuild). If a nested library module dir is ever added
# under core/src, add it here.
key: xcframework-${{ runner.os }}-${{ hashFiles('core/src/*.rs', 'core/src/cosign_core.udl', 'core/Cargo.toml', 'core/Cargo.lock', 'core/build.rs', 'core/uniffi.toml', 'scripts/build-rust.sh', 'scripts/build-xcframework.sh') }}
- name: Build XCFramework
if: steps.xcframework.outputs.cache-hit != 'true'
run: ./scripts/build-xcframework.sh
- name: Install Tuist + SwiftLint
run: brew install tuist swiftlint
- name: Install SwiftFormat (pinned)
# Pin the formatter version. The runner image's preinstalled swiftformat
# drifts (0.62.x turned on new default rules that flag already-committed
# code), so an unpinned `brew install swiftformat` makes lint results depend
# on the image rather than the repo. Keep this in step with the version
# developers run locally.
env:
SWIFTFORMAT_VERSION: 0.61.1
run: |
curl -fsSL "https://github.com/nicklockwood/SwiftFormat/releases/download/${SWIFTFORMAT_VERSION}/swiftformat.zip" -o /tmp/swiftformat.zip
unzip -o -q /tmp/swiftformat.zip -d /tmp/swiftformat
chmod +x /tmp/swiftformat/swiftformat
echo "/tmp/swiftformat" >> "$GITHUB_PATH"
- name: swiftformat --lint
run: swiftformat --version && swiftformat --lint App/ Modules/
- name: swiftlint
run: swiftlint lint --quiet --strict App Modules
- name: Generate Xcode project
run: tuist generate --no-open
- name: Pick an available iPhone simulator
id: sim
run: |
DEVICE=$(xcrun simctl list devices available | grep -E " iPhone [0-9]+" | head -1 | sed 's/^[ \t]*//' | sed 's/ (.*//')
echo "Selected simulator: $DEVICE"
echo "device=$DEVICE" >> "$GITHUB_OUTPUT"
# Compile the app + all test bundles once, then run without rebuilding.
- name: Build for testing
env:
SIMULATOR_NAME: ${{ steps.sim.outputs.device }}
run: |
xcodebuild build-for-testing \
-workspace Cosign.xcworkspace \
-scheme Cosign-Workspace \
-destination "platform=iOS Simulator,name=$SIMULATOR_NAME,OS=latest" \
-configuration Debug
# PR/push runs the fast unit suite only. The design-screenshot UI
# walkthroughs (CosignDemoUITests) each boot the app and are slow; they run
# nightly and on demand via ui-tests.yml, off the hot path.
- name: Run unit tests
env:
SIMULATOR_NAME: ${{ steps.sim.outputs.device }}
run: |
xcodebuild test-without-building \
-workspace Cosign.xcworkspace \
-scheme Cosign-Workspace \
-destination "platform=iOS Simulator,name=$SIMULATOR_NAME,OS=latest" \
-skip-testing:CosignDemoUITests \
-retry-tests-on-failure \
-test-iterations 2
# Single aggregate check to require in branch protection. It always runs and
# passes as long as no needed job FAILED or was cancelled; a skipped job
# (path-filtered out) is fine. Requiring this one job means an irrelevant
# skipped job can never block a merge, while a real failure still does.
ci-ok:
name: CI OK
runs-on: ubuntu-latest
if: always()
needs: [changes, rust, cargo-deny, ios]
steps:
- name: Verify no required job failed
env:
RESULTS: ${{ join(needs.*.result, ' ') }}
run: |
echo "Job results: $RESULTS"
for r in $RESULTS; do
if [[ "$r" == "failure" || "$r" == "cancelled" ]]; then
echo "A CI job failed or was cancelled."
exit 1
fi
done
echo "All CI jobs succeeded or were skipped."