Contributing to OFEM¶
Thanks for considering a contribution! This is a small, focused open-source project. We welcome bug reports, feature ideas, code, docs, and design feedback.
Project communication¶
- All issues, PRs, code, comments, commit messages, and documentation are in English so anyone can contribute, regardless of where they are.
- Be kind. See CODE_OF_CONDUCT.md.
Reporting bugs and requesting features¶
Use GitHub Issues. There are templates for both. Search first to avoid duplicates.
For security issues, do NOT open a public issue. See SECURITY.md.
Setting up your dev environment¶
See docs/prerequisites.md for the full list. TL;DR:
# clone
gh repo clone sdebruyn/onelake-explorer-macos
cd onelake-explorer-macos
# install dev tools
brew install commitlint xcodegen swiftformat swiftlint periphery
# generate the Xcode project
make gen
# compile the app + .appex unsigned — no Apple account needed, this is
# what CI runs on every PR
make build-ci
# run the unit tests (OfemKit engine + host app)
make test
# to build and run a signed app on your own Mac, you additionally need a
# paid Apple Developer Program membership (see prerequisites.md), then:
make build
You need Xcode for all work on this project. The entire codebase is Swift. make build-ci is enough to verify your change compiles — you don't need a paid Apple account to contribute code.
Branching and pull requests¶
- Branch off
main. - Name your branch like
feat/<short-description>,fix/<short-description>,docs/<short-description>. - Keep PRs small and focused. If a change touches multiple areas, see if it can be split.
- All PRs need passing CI: Swift build,
commitlint. - All PRs need at least one approving review (the maintainer's, for now). If you are the maintainer, you can self-merge.
Commit messages¶
We use Conventional Commits and enforce it in CI:
<type>(<optional scope>): <short summary in imperative mood>
[optional body explaining WHY, not what — the diff shows what]
[optional footer: BREAKING CHANGE, Refs #123, Closes #456]
Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert.
Examples:
feat(auth): persist tenant hint per-account for silent refresh
fix(onelake): honor Retry-After header on 429 responses
docs(plan): clarify exit criteria for signed builds
refactor(cache): extract SQLite schema into separate file
The release workflow uses these to auto-generate the release notes on each GitHub Release, so please keep them clean.
Code style¶
Swift¶
- SwiftFormat (nicklockwood/SwiftFormat 0.61.1) enforced in CI. Run
make formatto reformat in place;make format-lintto check without modifying (mirrors the CI gate). The.swiftformatconfig at the repo root controls rules and excludes. - SwiftLint (realm/SwiftLint 0.63.3) enforced in CI. Run
make lintto check locally (mirrors the CI gate). The.swiftlint.ymlconfig at the repo root controls rules and excludes. Error-level violations fail CI; warnings are informational. - Periphery (peripheryapp/periphery 3.7.4) detects dead code in CI. Run
periphery scanlocally to check. The.periphery.ymlconfig at the repo root controls targets and exclusions. Intentionally retained symbols (e.g. XPC protocol conformances, public API) are annotated with// periphery:ignore. The dead-code scan runs periphery in strict mode (any finding fails the job). It is not (yet) in the branch-protection required checks, so a finding surfaces as a red check rather than hard-blocking the merge button. - Use
os.log(unified logging) for everything that should land in Console.app. - Avoid blocking the File Provider Extension's main queue; everything should be async via
Task { … }. - Tests live in
Tests/in the OfemKit package and inOneLakeHostTests/for the host app. - OfemKit tests use swift-testing (
@Test); the host-app tests useXCTest. Prefer small, focused test functions with descriptive names.
Testing¶
- Unit tests run on every PR and merge to main, host-less and unsigned. They don't touch the network — OneLake and Fabric HTTP calls are mocked.
- Run them with
make test(OfemKit engine + host app), orcd Packages/OfemKit && swift testfor the engine alone. - Aim for >80% line coverage on
Packages/OfemKit/Sources/. - Integration tests run against a live Fabric workspace and exercise the real OneLake DFS data plane and Fabric REST discovery — no mocks. They are gated behind
OFEM_INTEGRATION=1and skipped in the normal unit-test pass. Run them withmake test-integration; this requires bearer tokens and workspace coordinates in the environment (OFEM_TOKEN_ONELAKE,OFEM_TOKEN_FABRIC,OFEM_TEST_WORKSPACE_ID,OFEM_TEST_LAKEHOUSE_ID) — see docs/auth.md for how CI provisions those. In CI they run on a schedule, on demand, and on any pull request that carries theintegrationlabel (via.github/workflows/integration.yml). - The warehouse tests additionally read a prepared Delta table. Seed it first with
scripts/prep_warehouse.sqlvia go-sqlcmd (brew install sqlcmd), which authenticates with youraz loginidentity — no password or secret:
sqlcmd -S "$OFEM_TEST_WH_SERVER" -d "$OFEM_TEST_WH_DATABASE" \
--authentication-method ActiveDirectoryAzCli \
-v table="$OFEM_TEST_WH_TABLE" -i scripts/prep_warehouse.sql -b
Then set OFEM_TEST_WAREHOUSE_ID to enable the warehouse suite. CI runs the seed step automatically before the tests.
Documentation¶
- Significant behavior changes go in
docs/and link from README if user-facing. - Markdown only. No images unless they show something not expressible in text.
- Use the doc per topic, not a giant README. See existing structure.
Releasing (maintainer)¶
GitHub Actions does the rest: build, sign, notarize, DMG, GitHub Release upload, cask bump.
See docs/packaging-homebrew.md for full pipeline details and docs/prerequisites.md for the secrets that must be configured.
Questions?¶
Open a Discussion or an Issue. Don't email — keep the conversation public so the next person can find it.