A git push from a Claude session is made with a bot token, and GitHub creates no workflow run for it — the branch moves and CI stays silent. Today that put a change on dev and then main having only ever been built after the fact, and both branches needed a manual workflow_dispatch to produce anything. Record the working rule that avoids it: push the feature branch, then open and merge the pull request through the GitHub API, whose calls are attributed to the repo owner and do trigger workflows. ci.yml already listens on pull_request for main and dev, so the PR is what builds the change before it lands. Also note what a merge actually does here — dev publishes a dev-channel prerelease, main publishes a production release — and that Gradle cannot run in the sandbox, so CI is the only verification available. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YEsqYAMJKUJoM7UAavm169
54 lines
2.5 KiB
Markdown
54 lines
2.5 KiB
Markdown
# Working on this repo with Claude
|
|
|
|
## Land changes through the GitHub API, never `git push` alone
|
|
|
|
**A `git push` from a Claude session does not trigger GitHub Actions.** The
|
|
sandbox pushes with a bot token, and GitHub creates no workflow run for it. The
|
|
branch updates, CI stays silent, and nothing gets built, tested or published.
|
|
|
|
The evidence, if it ever needs rechecking: every workflow run in this repo's
|
|
history is attributed to the repo owner. Commits *authored* by Claude trigger CI
|
|
normally — `d165e5ef`, `469c900e`, `d6e237ce` all did — because a human pushed
|
|
them. Commits pushed *by a session* (`43394b8`, `742add4`) produced no run at
|
|
all. It is the pushing credential that matters, not the commit author.
|
|
|
|
Calls through the GitHub API (the `mcp__github__*` tools) are attributed to the
|
|
repo owner and **do** trigger workflows. So:
|
|
|
|
1. Commit to a feature branch and `git push` it. This triggers nothing, which is
|
|
fine — a feature branch has no workflow of its own.
|
|
2. **Open a pull request via the API.** `ci.yml` runs on
|
|
`pull_request: [main, dev]`, so this is what actually builds and tests the
|
|
change. Wait for it to pass.
|
|
3. **Merge via the API.** The resulting push to `dev` or `main` is attributed to
|
|
the owner and triggers the branch's workflow.
|
|
|
|
Never merge by pushing `dev` or `main` directly from a session. It silently
|
|
skips every check and publishes nothing, leaving a branch whose head was never
|
|
built.
|
|
|
|
If a PR needs re-verifying after more commits, note that `synchronize` events
|
|
come from a raw push and are also dead. Trigger `ci.yml` manually with
|
|
`workflow_dispatch` instead.
|
|
|
|
## Merging is a shipping action
|
|
|
|
Both long-lived branches publish on push, so a merge is a release, not just an
|
|
integration:
|
|
|
|
- **`dev`** → `ci.yml` builds, tests, lints, then publishes a `v1.0.N-dev`
|
|
**prerelease**. Offered by the in-app updater to anyone on the Dev channel.
|
|
- **`main`** → `release.yml` publishes a **production** release. This is what
|
|
the updater installs for everyone on the Production channel.
|
|
|
|
Confirm before merging to `main`. Note that `release.yml` runs `assembleDebug`
|
|
only — no tests, no lint — so a `main` merge is only as verified as the `dev`
|
|
build it replays.
|
|
|
|
## Gradle does not run in the sandbox
|
|
|
|
`./gradlew` cannot resolve the Android plugin here: the proxy blocks
|
|
`dl.google.com` with a 403. There is no local build, no local test run, and no
|
|
local lint. CI is the only verification available, which is the other reason
|
|
changes must reach it through a PR before landing.
|