Platforms
Datasources and managers are platform-neutral. The platform is where the merge requests, the dashboard issue, the local> presets and the project listing live: one interface (publish.Platform) with two implementations.
- GitLab: proven in production across an estate of 200 repositories
- GitHub: proven against a fake that speaks the API and in a read-only run; the first production repository is outstanding
- Others: a package under
platform/, a test server, a case inwire
GitLab
Proven in production across an estate of 200 repositories.
| Variable | |
|---|---|
PINUP_GITLAB_URL / CI_SERVER_URL | the instance |
PINUP_GITLAB_TOKEN / GITLAB_TOKEN | a personal or project access token with api and write_repository; CI_JOB_TOKEN is used when none is set, and it can only read |
PINUP_REGISTRY_HOST / CI_REGISTRY | the instance's container registry, where the token is exchanged for a pull token |
Merge requests are found by source branch (open ones only; a closed one is history and is not reopened), created and aligned with title, description, labels and merge-when-pipeline-succeeds. An automerge the permissions refuse stands next to the request, not as an error. A request whose branch the plan no longer names is closed with autoclosed appended to its title. A commit's signature verdict comes from the API, so a run knows whether its commits show as Verified. The dashboard is the bot's own issue with exactly that title; an issue somebody else names that way is not the dashboard. local> presets come through the raw-file endpoint. Autodiscovery walks every non-archived project the token is a member of.
pinup token rotate renews the bot's own token before it expires and writes the new one into the CI variables it names, at group or project level. A job token cannot rotate itself.
GitHub
Proven against a fake that speaks the API, and in a read-only run against pinup's own mirror; the first production repository is outstanding.
| Variable | |
|---|---|
PINUP_PLATFORM=github | or implied by a GitHub token with no GitLab instance in the environment |
PINUP_GITHUB_URL / GITHUB_SERVER_URL | the host; github.com when empty; an Enterprise host under /api/v3 |
PINUP_GITHUB_TOKEN / GITHUB_TOKEN | classic repo, or fine-grained with contents, pull requests and issues read/write; on github.com it serves the github-* datasources as well |
Pull requests are found by head as owner:branch (a fork's branch of the same name is a different request), created and aligned (title, body, labels). Auto-merge is armed and withdrawn over GraphQL, the only API GitHub has for it; “not yet” (nothing to wait for) is told apart from “not allowed” (repository setting), and the latter stands next to the request. git authenticates through the askpass as x-access-token. The dashboard is the bot's own issue with exactly that title; the pull requests the issues endpoint returns along with it stay out. Autodiscovery lists the repositories the token may push to and that are not archived.
What GitHub does not know is said, not simulated: a request cannot ask for its branch to be deleted on merge (that is the repository setting delete_branch_on_merge), and auto-merge needs a repository that allows it.
Adding one
An implementation is a package under platform/ with the methods of publish.Platform, an iface.go that asserts them, a test server that speaks the protocol (pagination included) behind the refusing transport, a case in wire.Platform and one in the environment reader. Gitea and Forgejo are close to GitLab's shape.