diff --git a/.github/workflows/ci-kotlin.yml b/.github/workflows/ci-kotlin.yml deleted file mode 100644 index db40150..0000000 --- a/.github/workflows/ci-kotlin.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: CI (Kotlin) - -on: - push: - branches: ["kotlin", "release/kotlin*"] - pull_request: - branches: ["kotlin", "release/kotlin*"] - -jobs: - fmt: - name: Kotlin & Docs Formatting - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.23" - - - name: Check Go formatting - run: | - if [ -d tools ]; then - UNFORMATTED=$(gofmt -l tools/) - if [ -n "$UNFORMATTED" ]; then - echo "The following Go files are not formatted:" - echo "$UNFORMATTED" - echo "Run 'gofmt -w tools/' to fix." - exit 1 - fi - fi - - - name: Set up Node.js - uses: actions/setup-node@v5 - with: - node-version: "20" - - - name: Check Markdown formatting - run: npx prettier --check "**/*.md" - - test: - name: Please Build & Test (Kotlin) - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Build all targets - run: ./pleasew --plain_output build //tools/please_kotlin/... //test/kotlin/... - - - name: Run all tests - run: ./pleasew --plain_output test //... diff --git a/.github/workflows/ci-rust.yml b/.github/workflows/ci-rust.yml deleted file mode 100644 index d809da9..0000000 --- a/.github/workflows/ci-rust.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: CI (Rust) - -on: - push: - branches: ["rust", "release/rust*"] - pull_request: - branches: ["rust", "release/rust*"] - -jobs: - fmt: - name: Rust & Docs Formatting - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.23" - - - name: Check Go formatting - run: | - if [ -d tools ]; then - UNFORMATTED=$(gofmt -l tools/) - if [ -n "$UNFORMATTED" ]; then - echo "The following Go files are not formatted:" - echo "$UNFORMATTED" - echo "Run 'gofmt -w tools/' to fix." - exit 1 - fi - fi - - - name: Install rustfmt - uses: dtolnay/rust-toolchain@stable - with: - components: rustfmt - - - name: Check Rust formatting - run: | - if [ -d test ]; then - find test -name "*.rs" -exec rustfmt --check {} + - fi - - - name: Set up Node.js - uses: actions/setup-node@v5 - with: - node-version: "20" - - - name: Check Markdown formatting - run: npx prettier --check "**/*.md" - - test: - name: Please Build & Test (Rust) - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Build all targets - run: ./pleasew --plain_output build //tools/please_rust/... //test/rust/... - - - name: Run all tests - run: ./pleasew --plain_output test //... diff --git a/.github/workflows/ci-swift.yml b/.github/workflows/ci-swift.yml deleted file mode 100644 index 5fb6435..0000000 --- a/.github/workflows/ci-swift.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: CI (Swift) - -on: - push: - branches: ["swift", "release/swift*"] - pull_request: - branches: ["swift", "release/swift*"] - -jobs: - fmt: - name: Swift, Go & Docs Formatting - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.23" - - - name: Check Go formatting - run: | - if [ -d tools ]; then - UNFORMATTED=$(gofmt -l tools/) - if [ -n "$UNFORMATTED" ]; then - echo "The following Go files are not formatted:" - echo "$UNFORMATTED" - echo "Run 'gofmt -w tools/' to fix." - exit 1 - fi - fi - - - name: Set up Node.js - uses: actions/setup-node@v5 - with: - node-version: "20" - - - name: Check Markdown formatting - run: npx prettier --check "**/*.md" - - test: - name: Please Build & Test (Swift) - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Set up Swift - uses: swift-actions/setup-swift@v2 - with: - swift-version: "6.0" - - - name: Build all targets - run: ./pleasew --plain_output build //tools/please_swift/... //tools/swift_toolchain/... //test/swift/... - - - name: Run all tests - run: ./pleasew --plain_output test //... diff --git a/.github/workflows/ci-ts.yml b/.github/workflows/ci-ts.yml deleted file mode 100644 index 326bc78..0000000 --- a/.github/workflows/ci-ts.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: CI (TypeScript) - -on: - push: - branches: ["ts", "release/ts*"] - pull_request: - branches: ["ts", "release/ts*"] - -jobs: - fmt: - name: TypeScript, Go & Docs Formatting - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.23" - - - name: Check Go formatting - run: | - if [ -d tools ]; then - UNFORMATTED=$(gofmt -l tools/) - if [ -n "$UNFORMATTED" ]; then - echo "The following Go files are not formatted:" - echo "$UNFORMATTED" - echo "Run 'gofmt -w tools/' to fix." - exit 1 - fi - fi - - - name: Set up Node.js - uses: actions/setup-node@v5 - with: - node-version: "20" - - - name: Check Markdown formatting - run: npx prettier --check "**/*.md" - - test: - name: Please Build & Test (TypeScript) - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Build targets - run: ./pleasew --plain_output build //tools/please_ts/... //tools/ts_toolchain/... //test/ts/... - - - name: Run all tests - run: ./pleasew --plain_output test //... diff --git a/AGENTS.md b/AGENTS.md index ccacef0..d605b8b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,12 @@ agents operating in this codebase MUST strictly adhere to the following rules: - GitHub Release names / titles MUST always follow the standardized format: `[] v` (e.g. `[Rust] v0.4.0`, `[Kotlin] v0.1.0`). +5. **Shared CI is edited on `main` only**: + - `.github/workflows/release.yml` and `.github/actions/*` are shared: never + edit them on a language branch, change them on `main` and let the sync + bring them down. Each language branch owns its `ci-.yml`; `main` does + not carry one. See [docs/ci.md](docs/ci.md). + --- ## 2. Plugin & Configuration Rules diff --git a/docs/README.md b/docs/README.md index 2345c40..c829ae2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -111,6 +111,9 @@ please-rules/ ## Tooling & Code Quality +- **[CI layout](ci.md)**: which workflow files `main` owns and which a language + branch owns, the shared composite actions, a template for a new language + branch, and how the downstream sync works. - **[Raw lcov Coverage Reports](coverage-lcov.md)**: where each test rule keeps its function and branch coverage, the format, per-language limits, and how to classify covered, uncovered and partly covered lines. diff --git a/docs/ci.md b/docs/ci.md new file mode 100644 index 0000000..ebd9451 --- /dev/null +++ b/docs/ci.md @@ -0,0 +1,86 @@ +# CI layout + +Who owns which CI file, and how a language branch builds on what `main` +provides. The aim is that `main` and a language branch never edit the same +lines, so the downstream sync (`main` to each language branch) does not +conflict. + +## Ownership + +| File | Lives on | Edited on | +| :-------------------------------------- | :------------------ | :------------------ | +| `.github/workflows/ci-main.yml` | `main` | `main` | +| `.github/workflows/release.yml` | `main` | `main` only | +| `.github/workflows/sync-downstream.yml` | `main` | `main` | +| `.github/actions/*` | `main` | `main` only | +| `.github/workflows/ci-.yml` | its language branch | its language branch | + +`main` does not carry `ci-.yml`: its triggers only fire for its own +branch, so it never ran on `main`, and a copy there was edited from both sides. + +**Never edit a shared file on a language branch.** `release.yml` and the actions +in `.github/actions/` come from `main` through the sync; change them on `main` +and the branches get the change with the next merge. `release.yml` is the same +on every branch: it builds each tool with Please (`//tools/:`). + +## Shared composite actions + +A language's `ci-.yml` calls these after checking the repository out: + +- `.github/actions/format-check`: `gofmt` on the Go tools and `prettier` on the + Markdown. +- `.github/actions/please-build-test`: builds `build-targets` with Please and + runs `test-targets` (both default to `//...`). + +Anything specific to a language stays in its own file: a formatter (`rustfmt`), +a toolchain to set up (Swift), caches, and the coverage smoke tests. + +## Starting a new language branch + +Create `.github/workflows/ci-.yml` on the new branch from this template +(here for `python`): + +```yaml +name: CI (Python) + +on: + push: + branches: ["python", "release/python*"] + pull_request: + branches: ["python", "release/python*"] + +jobs: + fmt: + name: Python & Docs Formatting + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Check formatting + uses: ./.github/actions/format-check + + test: + name: Please Build & Test (Python) + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Build and test + uses: ./.github/actions/please-build-test + with: + build-targets: //tools/please_python/... //test/python/... +``` + +Add the language to the matrix of `sync-downstream.yml` and to the tag patterns +and options of `release.yml` on `main`. + +## The downstream sync + +`sync-downstream.yml` merges `main` into every language branch on each push to +`main`, runs the build and tests there, and pushes. It stops with an error if +the merge conflicts. Resolve it by hand: in the language branch run +`git merge main`, fix the conflicts, and push (never rebase a published branch). +A conflict means a shared file was edited on a branch, so move that change to +`main`.