deploys-app/Build and Deploy to Deploys.app

Build a Dockerfile, push it to registry.deploys.app, and deploy — keyless via GitHub OIDC. Pull requests get temporary preview deployments with a sticky preview comment and GitHub deployment statuses.

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Activelast commit Jun 25, 2026
License
MIT

Pinned Snippet

workflow.ymlSHA-pinned
uses: deploys-app/build-deploy-action@0716b3e3f24dcda7c469bfba4ed84ceeccc41b18 # v1.4.0

tags can be moved; commit SHAs can't. why a SHA?

namedescriptionrequireddefault
projectProject IDyes
locationDeploy location ID (e.g. gke.cluster-rcf2)yes
nameBase deployment name. Pull request runs deploy to <name>-pr-<number>.yes
modeBuild mode: `dockerfile` (default) builds and pushes a container image; `static` builds a static site, uploads it as a content-addressed release, and deploys it as a Static deployment (no image, no port, no registry).nodockerfile
workingDirectoryRoot folder of the app to build, relative to the repo — for monorepos, e.g. apps/web. In dockerfile mode the build context and the default Dockerfile path resolve under it; in static mode the build command runs inside it and outputDir is read relative to it. Defaults to the repo root.no.
contextDocker build context, resolved relative to workingDirectoryno.
dockerfileDockerfile path, resolved relative to workingDirectory (default <workingDirectory>/<context>/Dockerfile)no""
buildArgsDocker build args, one KEY=VALUE per lineno""
frameworkStatic build framework (mode=static only): `auto` (default) detects Hugo via .tool-versions/hugo.toml/config.toml, else Node via package.json; `hugo` forces Hugo extended; `node` forces Node; `none` requires an explicit buildCommand.noauto
buildCommandStatic build command (mode=static only). Defaults per framework: Hugo -> `hugo --minify` if the repo Makefile's build target uses it else `hugo`; Node -> `npm run build`. Required when framework=none.no""
outputDirBuilt static tree to upload (mode=static only). `public` for Hugo, `dist`/`build` for Node SPAs.nopublic
nodeVersionNode toolchain version for the `node` framework (mode=static only). Defaults to .nvmrc/.tool-versions, else 20.no""
spaSPA fallback to index.html on unknown routes (mode=static only). Default false — Hugo sites are not SPAs (clean-URL resolution + a real 404). Set true for Vite/React SPAs.nofalse
notFoundCustom 404 document served on clean-URL misses when spa=false (mode=static only).no404.html
baseUrlBuild-time base URL (mode=static only). If empty, the action injects the planned deploy URL (production or preview host, resolved via location.get) so sitemap.xml/RSS carry the correct host.no""
uploadConcurrencyHow many static blobs to upload in parallel (mode=static only). Static publish is round-trip bound — one small idempotent PUT per file — so uploading concurrently is the dominant speedup. Default 16; raise it for very large sites, or set 1 to force the old one-at-a-time behaviour.no16
portContainer port (WebService/TCPService)no8080
typeDeployment type (WebService, Worker, TCPService, InternalTCPService)noWebService
protocolApplication protocol for a WebService (mode=dockerfile): `http` (default), `https`, or `h2c` (HTTP/2 cleartext, e.g. gRPC backends). Ignored for other deployment types and for static deployments.no""
envEnvironment variables for the deployment, one KEY=VALUE per line (dockerfile mode only). Ignored in static mode — a static site has no runtime container to read them.no""
envGroupsEnv groups to attach to the deployment, one per line or comma-separated. Each must already exist in the project (envGroup.create / the console). Dockerfile mode only — ignored in static mode (no runtime container).no""
pullSecretPull secret name for the image registry (dockerfile mode only). Use this when the deployment must authenticate to a private registry; the secret must already exist in the deploy location. Ignored in static mode.no""
requireGoogleLoginGate the deployment behind Google login (deployment access). Default false — the deployment is public. Applies to both container and static deployments; programmatic/API clients cannot bypass the gate.nofalse
allowedEmailsEmails allowed through the access gate, one per line or comma-separated. Only applies when requireGoogleLogin is true; empty means any signed-in Google account is allowed.no""
allowedDomainsEmail domains allowed through the access gate (e.g. example.com), one per line or comma-separated. Only applies when requireGoogleLogin is true; empty means any signed-in Google account is allowed.no""
previewTtlPreview deployment TTL (Ns/Nm/Nh/Nd), re-applied on every push so it rolls. Previews are also deleted when the pull request closes.no7d
apiEndpointDeploys.app API endpointnohttps://api.deploys.app
registryDeploys.app registry hostnoregistry.deploys.app
buildkitEndpointRemote BuildKit address to build on instead of a local builder on the runner (mode=dockerfile). Example: `tcp://buildkit.internal:1234`. Empty (default) builds with a local BuildKit on the runner — unchanged behaviour. The runner must be able to reach the endpoint (a self-hosted runner, or a publicly reachable / tunnelled address). A plain `tcp://` endpoint is unencrypted; supply the TLS inputs below for mTLS.no""
buildkitCaCertCA certificate (PEM) for a TLS remote BuildKit (mode=dockerfile). Pass from a secret. Set together with `buildkitCert` and `buildkitKey` to reach `buildkitEndpoint` over mTLS.no""
buildkitCertClient certificate (PEM) for a TLS remote BuildKit (mode=dockerfile). Pass from a secret. See `buildkitCaCert`.no""
buildkitKeyClient private key (PEM) for a TLS remote BuildKit (mode=dockerfile). Pass from a secret. See `buildkitCaCert`.no""
namedescription
deploymentThe deployed deployment name (base name, or <name>-pr-<n> for previews)
environmentproduction, or pr-<n> for previews
artifactThe deployed artifact: the pushed image in digest form (mode=dockerfile) or the static release-sha (mode=static).
imageDeprecated alias of `artifact` (the pushed image in digest form for mode=dockerfile). Kept for one minor version; use `artifact`.
urlThe deployed URL