This repository ships a GitHub Action implemented in Go.
- Action definition:
action.yml - Action type:
composite - Runtime binary: prebuilt amd64 Linux artifact in
dist/ - No Docker image build is required during action execution.
- Go commands should be run via
misefor toolchain consistency. - Examples:
make testmake distmise exec -- go test ./...mise exec -- go run ./cmd/pullpreview up examples/example-app
- Run
make testbefore any push. - Changelog updates are maintained in GitHub Releases;
CHANGELOG.mddoes not need to be amended for routine release notes. - Always run
make distbefore pushing source changes so the bundled CLI binary stays in sync. make distbuilds the prebuilt Linux binary underdist/and auto-commits only that directory via the repo’sdist-committarget.- Dist workflow:
- Commit source changes first.
- Run
make distafterwards. make distauto-commits the updated bundled binary with a standard commit message.- Before merging,
make rewritecan rewrite the current branch and drop dist-only auto-commits (force-push required).
Entrypoint source is cmd/pullpreview/main.go.
Supported commands:
pullpreview up path/to/apppullpreview down --name <instance>pullpreview list org/repopullpreview github-sync path/to/app
- Default provider:
lightsail. - Supported providers:
lightsail,hetzner. - Provider discovery is via
internal/providersregistrations. - New Hetzner provider is implemented in
internal/providers/hetzner. providerspackage uses typed environment config parsing and factory registration.
- Launches/restores an instance via provider abstraction.
- Waits for SSH and runs provider-generated user-data.
- Uploads authorized SSH keys.
- Renders compose config, rewrites relative bind mounts under
app_pathto/app/..., and syncs only detected bind-mounted local paths viarsync. - Deploys through Docker context on remote engine.
- Executes
pre_scriptinline over SSH beforedocker compose up. - Optional HTTPS via
proxy_tlsinjects a Caddy sidecar and adjusts logging/port exposure. - Emits heartbeat logs with:
- preview URL
- SSH command (
ssh user@ip) - authorized users info
- key upload status
- Handles PR labeled/opened/reopened/synchronize/unlabeled/closed events.
- Handles scheduled cleanup of dangling labeled preview instances.
- Updates marker-based PR status comments.
- For
admins: "@collaborators/push":- loads collaborators from GitHub REST API with
affiliation=all+permission=push - uses only the first page (up to 100 users)
- emits warning if additional pages exist
- fetches each admin's SSH public keys via GitHub API and forwards keys to the instance
- uses local key cache directory (
PULLPREVIEW_SSH_KEYS_CACHE_DIR) to avoid refetching keys across runs
- loads collaborators from GitHub REST API with
- Always posts/updates marker-based PR status comments per environment/job with building/ready/error/destroyed state and preview URL.
- Existing inputs are preserved.
- Provider-related inputs are:
providerregionimageinstance_typeproxy_tls
- Hetzner uses shared inputs (
region/imageandinstance_type) andHCLOUD_TOKENcredentials. - Outputs:
urlhostusername
- File paths:
internal/providers/hetzner/hetzner.go- provider registration:
internal/providers/hetzner - shared user-data fallback remains in
internal/pullpreview/user_data.go - Hetzner custom user-data in
Provider.BuildUserData
- Defaults:
- location:
nbg1 - image:
ubuntu-24.04 - server type:
cpx21 - username:
root
- location:
- SSH keys are cached for re-entry via
PULLPREVIEW_SSH_KEYS_CACHE_DIR. downcurrently accepts both normalized instance names and compose context names (pullpreview-*) through normalization inRunDown.- Lifecycle cleanup follows best-effort ordering in provider:
- recreate missing cache/server state when stale
- validate SSH, recreate instance if cache/validation fails
- destroy server before cleanup paths on failure
cmd/pullpreview: CLIinternal/pullpreview: core orchestrationinternal/providers: provider registry and concrete providersinternal/github: GitHub API wrapperinternal/license: license check clientdist/: bundled Linux amd64 binary used by the action
skills/pullpreview-demo-flow/SKILL.md: repeatable end-to-end demo capture workflow (PR open/label/deploy/view deployment/unlabel/destroy) with strict screenshot requirements and fixed demo PR title.
- Live provider validation has been run against Hetzner using
.envwithHCLOUD_TOKENplus CLI/action values (--region nbg1,instance_type cpx21,--image ubuntu-24.04). up,down, andlistflows have been exercised.- Follow-up cleanup items:
- tighten
RunDowncontext-name parser to avoid stripping legitimate names that resemble context suffix format - make create-failure cleanup continue best-effort cache/key cleanup if server delete fails
- tighten