Skip to content

fix(host): legible needs-sign-in status color + rename action to "Sig… #700

fix(host): legible needs-sign-in status color + rename action to "Sig…

fix(host): legible needs-sign-in status color + rename action to "Sig… #700

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build:
name: Build + smoke tests
runs-on: macos-15
timeout-minutes: 30
env:
DEVELOPER_DIR: /Applications/Xcode_16.3.app/Contents/Developer
steps:
- uses: actions/checkout@v6.0.3
- name: Assert Xcode 16.3 is present
# Fail fast if the runner image no longer ships Xcode 16.3 rather
# than silently falling back to a different Xcode version.
run: |
set -euo pipefail
if [ ! -d /Applications/Xcode_16.3.app ]; then
echo "ERROR: Xcode_16.3.app not found at /Applications/Xcode_16.3.app" >&2
echo "Available Xcode installations:" >&2
ls /Applications/Xcode*.app 2>/dev/null || echo " (none found)" >&2
exit 1
fi
xcodebuild -version
- name: Check bundle-ID consistency
# Asserts bundle IDs, team prefix, and app-group are consistent across
# OfemPaths.swift, project.yml, the cask template, and release.yml.
# Fails fast if they drift so regressions surface at PR time, not at
# notarization. The full single-source xcconfig refactor is deferred to
# a dedicated signed-release-validated PR; this guard covers the gap.
run: bash scripts/check-bundle-ids.sh
- name: Cache Homebrew downloads
uses: actions/cache@v5.0.5
with:
path: |
~/Library/Caches/Homebrew/downloads
~/Library/Caches/Homebrew/api
key: brew-${{ runner.os }}-xcodegen-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: |
brew-${{ runner.os }}-xcodegen-
- name: Cache SwiftPM build artifacts
# Cache .build and the Xcode DerivedData SourcePackages folder keyed on
# the lockfile so MSAL, GRDB, and TOMLKit are not re-resolved/recompiled
# on every run. The restore-key falls back to a prior run's cache when
# Package.resolved has not changed, accepting a slightly stale build
# artifact cache that re-increments on the next full build.
uses: actions/cache@v5.0.5
with:
path: |
Packages/OfemKit/.build
DerivedData/SourcePackages
key: spm-${{ runner.os }}-${{ hashFiles('Packages/OfemKit/Package.resolved') }}
restore-keys: |
spm-${{ runner.os }}-
- name: Install xcodegen
run: brew install xcodegen
- name: Bootstrap local xcconfig
# CI has no signing identity; the sample file's placeholder
# DEVELOPMENT_TEAM is harmless because every xcodebuild invocation
# below disables code signing (CODE_SIGNING_ALLOWED=NO).
run: make bootstrap
- name: Generate Xcode project
run: make gen
- name: Verify project.pbxproj exists
run: test -f OneLake.xcodeproj/project.pbxproj
- name: Smoke tests (unsigned, host-less)
# Runs the host-app logic bundle (OneLakeHostTests) and the FPE logic
# bundle (OneLakeFileProviderTests). Runs before the slower full app
# build so a Swift compile regression surfaces in seconds.
# `make test` writes DerivedData/HostTests.xcresult and
# DerivedData/FPETests.xcresult with coverage for Codecov upload below.
run: make test
- name: Export host-app coverage
run: |
set -euo pipefail
brew install xcresultparser
xrp="$(brew --prefix xcresultparser)/bin/xcresultparser"
"$xrp" --output-format cobertura \
DerivedData/HostTests.xcresult > host-coverage.xml
# xcresultparser emits absolute filename paths; strip the workspace
# prefix so they are repo-relative (e.g. OneLake/Foo.swift), which is
# what Codecov needs to map coverage onto the tree.
sed "s|${GITHUB_WORKSPACE}/||g" host-coverage.xml > host-coverage.xml.tmp
mv host-coverage.xml.tmp host-coverage.xml
echo "host-coverage.xml: $(wc -l < host-coverage.xml) lines"
- name: Upload host coverage to Codecov
uses: codecov/codecov-action@v7.0.0
with:
files: host-coverage.xml
flags: host
disable_search: true
# Never fail the build on a Codecov hiccup or a fork PR with no token.
fail_ci_if_error: false
- name: Export FPE coverage
run: |
set -euo pipefail
xrp="$(brew --prefix xcresultparser)/bin/xcresultparser"
"$xrp" --output-format cobertura \
DerivedData/FPETests.xcresult > fpe-coverage.xml
sed "s|${GITHUB_WORKSPACE}/||g" fpe-coverage.xml > fpe-coverage.xml.tmp
mv fpe-coverage.xml.tmp fpe-coverage.xml
echo "fpe-coverage.xml: $(wc -l < fpe-coverage.xml) lines"
- name: Upload FPE coverage to Codecov
uses: codecov/codecov-action@v7.0.0
with:
files: fpe-coverage.xml
flags: fpe
disable_search: true
fail_ci_if_error: false
- name: Build app + extension (unsigned)
# Compiles the OneLake app and the File Provider .appex with code
# signing disabled. Catches Swift compile regressions on every PR
# so they no longer surface for the first time on a release tag.
run: make build-ci
ofemkit-tests:
name: OfemKit package tests
runs-on: macos-15
timeout-minutes: 20
env:
DEVELOPER_DIR: /Applications/Xcode_16.3.app/Contents/Developer
steps:
- uses: actions/checkout@v6.0.3
- name: Assert Xcode 16.3 is present
run: |
set -euo pipefail
if [ ! -d /Applications/Xcode_16.3.app ]; then
echo "ERROR: Xcode_16.3.app not found at /Applications/Xcode_16.3.app" >&2
ls /Applications/Xcode*.app 2>/dev/null || echo " (none found)" >&2
exit 1
fi
xcodebuild -version
- name: Cache SwiftPM build artifacts
uses: actions/cache@v5.0.5
with:
path: |
Packages/OfemKit/.build
key: spm-${{ runner.os }}-${{ hashFiles('Packages/OfemKit/Package.resolved') }}
restore-keys: |
spm-${{ runner.os }}-
- name: Validate Package.resolved is in sync
# Ensures the committed lockfile matches Package.swift before running
# tests, so CI surfaces drift early rather than at release time.
working-directory: Packages/OfemKit
run: |
set -euo pipefail
swift package resolve --only-use-versions-from-resolved-file 2>/dev/null || \
swift package resolve
if ! git diff --quiet -- Package.resolved; then
echo "ERROR: Package.resolved drifted from Package.swift — commit the updated lockfile." >&2
git diff -- Package.resolved >&2
exit 1
fi
- name: Run OfemKit tests
# The engine package owns all sync/auth/cache logic. No xcodegen
# is needed — `swift test` resolves from Package.resolved directly.
# --enable-code-coverage emits LLVM profiles for the Codecov upload below.
working-directory: Packages/OfemKit
run: swift test --enable-code-coverage
- name: Export coverage to lcov
working-directory: Packages/OfemKit
run: |
set -euo pipefail
bin=$(swift build --show-bin-path)
profdata="$bin/codecov/default.profdata"
# The test bundle's executable lives inside the .xctest on macOS.
xctest=$(find "$bin" -path '*.xctest/Contents/MacOS/*' -type f -name 'OfemKitPackageTests' | head -1)
test -n "$xctest" || { echo "OfemKit test bundle not found under $bin" >&2; exit 1; }
xcrun llvm-cov export -format=lcov \
-instr-profile "$profdata" "$xctest" \
-ignore-filename-regex='(/Tests/|/\.build/)' > coverage.lcov
# llvm-cov emits absolute compile paths; strip the workspace prefix so
# the SF: paths are repo-relative (e.g. Packages/OfemKit/Sources/...),
# which is what Codecov needs to map coverage onto the tree.
sed "s|${GITHUB_WORKSPACE}/||g" coverage.lcov > coverage.lcov.tmp
mv coverage.lcov.tmp coverage.lcov
echo "wrote coverage.lcov ($(wc -l < coverage.lcov) lines)"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v7.0.0
with:
files: Packages/OfemKit/coverage.lcov
flags: ofemkit
disable_search: true
# Never fail the build on a Codecov hiccup or a fork PR with no token.
fail_ci_if_error: false
commitlint:
name: Commitlint
runs-on: ubuntu-latest
timeout-minutes: 10
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v6.0.3
with:
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@v6.4.0
with:
node-version: "22"
- name: Install commitlint
run: npm install --no-save @commitlint/cli@19.8.1 @commitlint/config-conventional@19.8.1
- name: Validate PR commits
# Use the merge-base rather than base.sha so commitlint validates only
# the commits on this PR branch, not stale base commits that diverged
# after a force-push or after main advanced since the branch was cut.
run: |
npx commitlint \
--from "$(git merge-base origin/${{ github.event.pull_request.base.ref }} HEAD)" \
--to HEAD \
--verbose