GitHub composite action that proposes end-to-end Lark tests for each pull request and creates them on demand. Drop it into a workflow and Lark will draft suggestions, post them as a PR comment, and — when a maintainer replies /create-workflows — materialize the approved subset as real Lark workflows.
Under the hood, Claude Code reads the diff and discovers your existing coverage by calling the Lark MCP server — searching workflows by name and inspecting their steps before proposing anything new, then using the same MCP server's create_workflow tool to materialize each approved proposal.
The action runs in two phases off the same getlark/lark-github-actions-app@v1 step — it branches internally on github.event_name:
- Propose (on
pull_requestopen/reopen) — Claude drafts test proposals, the action posts them as a PR comment with a hidden JSON marker, and labels the PRlark:tests-proposed. - Create (on
issue_commentwith body/create-workflowsor/create-workflows 1 3 …) — only repo collaborators withwrite,maintain, oradminpermission can trigger this. The action re-reads the most recent proposals comment, filters by the listed 1-based indices (or takes all of them), and asks Claude to create one Lark workflow per entry. A new PR comment lists the created workflow ids and dashboard links.
# .github/workflows/lark.yml
name: Lark — propose and create tests
on:
pull_request:
types: [opened, reopened]
issue_comment:
types: [created]
permissions:
id-token: write
pull-requests: write
contents: read
jobs:
lark:
# Skip PRs from forks — they cannot mint OIDC tokens with our trusted audience.
# For comment events we additionally guard on `issue.pull_request != null` so
# the job never runs on plain issue comments.
if: >-
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request != null)
runs-on: ubuntu-latest
steps:
- uses: getlark/lark-github-actions-app@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}| Name | Required | Default | Description |
|---|---|---|---|
anthropic-api-key |
yes | — | Anthropic API key used by claude-code-action to draft proposals. Pass via ${{ secrets.ANTHROPIC_API_KEY }} so GitHub masks it in logs. |
lark-api-base-url |
no | https://api.getlark.ai |
Override to point at staging. Production customers should leave the default. |
claude-model |
no | sonnet |
Claude model passed to claude-code-action via --model. Override to e.g. opus for higher-fidelity proposals. |
| Permission | Why |
|---|---|
id-token: write |
Mint the OIDC token that Lark exchanges for a scoped API token. |
pull-requests: write |
Post the proposals/results comments, manage the lark:* labels, and add reactions to /create-workflows comments. |
contents: read |
Check out the PR head so Claude Code can diff against the base. |
This action follows the GitHub Actions standard floating-major-tag pattern:
- Immutable point releases: every release gets an immutable annotated tag, e.g.
v1.0.0,v1.0.1,v1.1.0. - Floating major tag:
v1is a lightweight tag that is force-moved to the latestv1.x.xcommit on every release. Customers pingetlark/lark-github-actions-app@v1and automatically pick up patch and minor releases. - Breaking changes bump the major tag —
v2.0.0ships alongside a new floatingv2tag. The oldv1keeps pointing at the lastv1.x.xso existing customer workflows do not break.
# 1. Tag the new immutable version.
git tag -a v1.0.1 -m "v1.0.1"
git push origin v1.0.1
# 2. Re-point the floating major tag.
git tag -f v1 v1.0.1
git push origin v1 --forceAlways create the immutable tag first and push it before moving the floating tag — that way the floating tag never points at a commit that is not also reachable from a permanent tag.