Keep your GitHub project board up to date automatically. When your team opens issues and pull requests, the right card appears in the right column. When work moves, the card moves. Nobody drags cards by hand.
Setup takes about a minute.
| What happens | Where the card goes |
|---|---|
| Someone opens an issue | A card appears in Backlog |
| Someone reopens an issue | Back to Todo |
| Someone opens a pull request that fixes an issue | The pull request and the issue move to In Progress |
| Someone asks for a review | In Review |
| A reviewer asks for changes | Back to In Progress |
| Someone approves the review | Nothing changes (that is on purpose) |
| The pull request is closed without merging | The issue goes back to Todo |
| The pull request is merged | The issue closes and the card moves to Done |
Moving an issue from Backlog to Todo stays a human decision: that is triage.
The tools are gh (GitHub's command line) and jq. How you install them
depends on your computer:
| Your computer | Open this | Paste this |
|---|---|---|
| Mac | Terminal | brew install gh jq (if brew is not recognized, install Homebrew first from https://brew.sh) |
| Windows | WSL or Git Bash | winget install GitHub.cli then install jq from https://jqlang.github.io/jq/download (jq.exe belongs in your PATH) |
| Linux | your terminal | sudo apt install gh jq (Ubuntu, Debian) or sudo dnf install gh jq (Fedora) |
Windows users: the setup script needs a bash shell, so use WSL (recommended,
one command: wsl --install then open the WSL terminal) or Git Bash. If you
are on Windows Server or something older, see docs/troubleshooting.md.
Not sure what a terminal is? It is the window where you type commands instead of clicking buttons. On a Mac, press Command and Space, type Terminal, press Enter.
gh auth login
Answer the questions it asks. Choose GitHub.com, HTTPS, and log in with your browser.
On github.com, go to your profile or organization page, click Projects, and create a new project (Table or Board view both work). Give it the columns Backlog, Todo, In Progress, In Review, and Done. New boards start with only Todo, In Progress, and Done, so add Backlog and In Review by clicking the plus sign at the right end of the board.
The board's address looks like
https://github.com/users/YOUR-NAME/projects/3. That last number (here, 3) is
your project number. Write it down.
A token is a long password that lets the automation touch your board.
- On github.com, click your profile picture, then Settings
- Scroll to the bottom of the left sidebar and click Developer settings
- Click Personal access tokens, then Tokens (classic)
- Click Generate new token (classic)
- Give it a name like board automation, pick an expiration date
- Tick the checkboxes called
repoandproject - Click Generate new token and copy the long token it shows (it starts with
ghp_)
Personal boards need this classic token. (Fine-grained tokens, the newer kind, cannot touch personal boards. Org boards can use either.)
git clone https://github.com/stbensonimoh/github-board-automation.git
cd github-board-automation
printf '%s' "PASTE YOUR TOKEN HERE" | bash scripts/setup.sh --owner YOUR-NAME --project-number YOUR-NUMBER --repos YOUR-NAME/YOUR-REPO --individual-mode copy --token-expiry 2027-06-01
Replace the parts in capital letters: your GitHub name, your project number, your repo, and a date about six months out (the tool reminds you when the token expires). Paste your token where it says PASTE YOUR TOKEN HERE.
Running organizations: use docs/install-org.md. Anything else: see docs/install-individual.md and docs/troubleshooting.md.
Open a test issue in your repo. Within about a minute, a card appears on your
board in Backlog. Open a pull request that says Closes #1 in its
description, and watch it move.
The board is a state machine:
| Event | Result |
|---|---|
| Issue opened | Backlog |
| Issue reopened | Todo |
| PR opened or reopened | PR plus linked issues (same repo close keywords) In Progress |
| Review requested | In Review |
| Review approved or commented | no change (no-op) |
| Changes requested | back to In Progress |
| PR closed unmerged | linked issues back to Todo unless another open PR still closes them |
| PR merged | the issue closes and the board's native Item closed workflow moves the card to Done |
Backlog to Todo triage stays manual. Closes #N style keywords link PRs to
issues, same repo only, case insensitive.
- Does this run once, or for every project? Once per project board. Each board needs its own run of the command.
- Several repos, one board? Yes. Orgs list them all in one command. Personal accounts: run the command again with the same project number and the next repo.
- Do I clone this tool again for a new project? No. Open the folder you
cloned (
cd github-board-automation) and run the command again with the new project number. - Want to stop using it on a repo? Remove the
board-sync.ymlfile from the repo and delete the two secrets. Both guides cover this at the bottom.
bats installs locally (brew install bats-core on a Mac, apt install bats on Debian or Ubuntu); the two lint gates run
in Docker, so no local install is needed. Run all three before opening a PR:
docker run --rm -v "$PWD":/mnt -w /mnt koalaman/shellcheck@sha256:2097951f02e735b613f4a34de20c40f937a6c8f18ecb170612c88c34517221fb --severity=warning $(find scripts tests -name '*.sh' -type f)
docker run --rm -v "$PWD":/repo -w /repo rhysd/actionlint@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667 -color .github/workflows/*.yml templates/*.yml
bats tests/Images are pinned by digest so local runs match CI exactly. CI runs the same
three checks on every PR. SPEC.md is the full spec; docs/ carries the
install guides and troubleshooting.
E2E evidence files do not get committed. The harness writes them under
tests/e2e/evidence/, and that directory is ignored by git. When a PR claims
an E2E pass, attach the Actions run URL and the JSON to the PR.
- docs/install-org.md: the org walkthrough
- docs/install-individual.md: the personal walkthrough, both install styles
- docs/troubleshooting.md: what to do when something fails
MIT. See LICENSE.