Deploy

GitHub Deployment

Use GitHub Repository as the project source when you want to publish the application from source code and the build flow configured during creation.

Required permissions

ActionMinimum scope
Create an HTTP projectproject.create on organization:*
Configure the repository or GitHub commandsproject.source.update on project:<project-id>
Trigger a manual deploymentproject.deploy.trigger on project:<project-id>
Read builds and logsproject.logs.read on project:<project-id>

owner has full access. assistant, member, and organization API Keys need the corresponding grants.

Prerequisites

Before selecting a repository, complete these two required steps:

Note: The GitHub App can be installed on a personal account or an organization. In organizations, installation may require administrator approval.

Steps

  1. In the console, click Create Project.
  2. Choose GitHub Repository as the project source.
  3. Select the repository, branch, runtime, and project commands.
  4. Decide whether to enable auto-deploy.
  5. Click Create Project.

Project commands

In GitHub projects, Zenifra installs dependencies according to the selected runtime, runs pre-build and build during the build, and uses start when the application starts:

  • pre-build is optional
  • build is optional
  • start is required

This is the order of the steps. Some projects only need start, while others also use pre-build and build.

Node.js dependencies

With the Node.js runtime, dependency installation runs npm ci before any pre-build or build command. For this flow to work:

  • keep package.json and a valid package-lock.json in the same application root directory on the selected branch
  • generate and commit package-lock.json whenever dependencies change
  • verify the project locally with the same Node.js version selected for the project
npm ci
npm run build # only when the project has a build script
npm start

The package-lock.json must be synchronized with package.json. To use the commands in these examples, define the start script in package.json. Set the build field to npm run build only when the build script exists; otherwise, leave the field empty.

The pre-build command runs only after npm ci. It can prepare the application, but it cannot replace the initial installation with pnpm or Yarn. Projects and workspaces that depend on those package managers need careful adaptation to produce a compatible package-lock.json before using the current Node.js runtime. Zenifra does not automatically convert a pnpm- or Yarn-specific workspace to npm.

Build troubleshooting

Use Build Logs to identify the failed step and follow the matching guidance:

ErrorHow to fix it
Missing or unusable package-lock.jsonGenerate a valid npm lockfile, commit it next to package.json on the selected branch and root directory, then create a new build
package-lock.json is out of syncRun npm install to update the lockfile, commit the changes, verify with npm ci, and create a new build
GitHub repository access rejectedZenifra automatically attempts to renew the binding to the same repository. If the console still says authorization is required, use Reconnect repository in the project and start a new build
Commit unavailableCreate a new build from the current state of the selected branch. If the error continues for current commits, contact support
Unclassified causeReview Build Logs and the project commands. An unavailable additional diagnosis does not replace the recorded cause and does not require rotating project keys

Auto-deploy

When auto-deploy is enabled during project creation, each push to the selected branch triggers a new automatic update.

When auto-deploy is disabled, the project does not update automatically on push.

Preview Environments

Use Preview Environments to give each pull request a temporary URL without replacing the primary project. First enable the feature in the project's Previews tab and store the API Key in a GitHub secret.

The recommended workflow uses opened, synchronize, reopened, and closed events. With PREVIEW_ACTION=auto, the Action upserts on the first three events and removes the preview when the pull request closes. The same pull request reuses the automatic pr-<number> key.

name: Zenifra preview

on:
  pull_request:
    types: [opened, synchronize, reopened, closed]

permissions:
  contents: read

jobs:
  preview:
    runs-on: ubuntu-latest
    steps:
      - name: Create or remove preview
        uses: zenifra/action-zenifra-deploy@v1
        with:
          PROJECT_ID: ${{ vars.ZENIFRA_PROJECT_ID }}
          API_KEY: ${{ secrets.ZENIFRA_API_KEY }}
          IMAGE: ${{ vars.ZENIFRA_PREVIEW_IMAGE }}
          PREVIEW: true
          PREVIEW_ACTION: auto
          PREVIEW_TTL: 24h
          WAIT_TIMEOUT: 10m

For a run outside a pull request, use workflow_dispatch and provide a stable PREVIEW_KEY:

on:
  workflow_dispatch:
    inputs:
      preview_key:
        description: Preview Environment key
        required: true
        type: string
      action:
        description: Operation
        required: true
        default: upsert
        type: choice
        options: [upsert, delete]

jobs:
  preview:
    runs-on: ubuntu-latest
    steps:
      - uses: zenifra/action-zenifra-deploy@v1
        with:
          PROJECT_ID: ${{ vars.ZENIFRA_PROJECT_ID }}
          API_KEY: ${{ secrets.ZENIFRA_API_KEY }}
          IMAGE: ${{ vars.ZENIFRA_PREVIEW_IMAGE }}
          PREVIEW: true
          PREVIEW_KEY: ${{ inputs.preview_key }}
          PREVIEW_ACTION: ${{ inputs.action }}

Outside a pull request, the key is required. A preview is billed hourly in BRL, has a default TTL of 24 hours, and accepts 1 to 168 hours. User variables are always copied inside Zenifra, but they may point to the same services as the primary project. Storage starts empty and isolated; data, custom domains, and custom image commands are not inherited.

The Action waits for availability with bounded polling and provides preview_id, preview_url, expires_at, operation_id, and preview_status. It never publishes API Keys or variable values in the Job Summary or logs.

What stays fixed after creation

In GitHub-based projects, these fields are defined during creation and are not available for editing later:

  • project source
  • branch
  • runtime
  • runtime version
  • auto-deploy

After creation, the confirmed editable settings for GitHub projects are pre-build, build, and start.

Build Logs

After the project is created, follow each publication from the Build Logs tab inside the project page in the console.

This history shows:

  • recent builds
  • current build status
  • dependency installation output
  • pre-build output, when present
  • build output, when present

Public build logs are filtered to prioritize useful project output.

The log modal updates in real time while the build is running.

Retention

GitHub build history is retained for up to:

  • 30 builds per project
  • 30 days of age

Whichever limit is reached first removes the oldest records.

URL

All plans receive a Zenifra URL in *.clients.zenifra.com. In higher plans, the subdomain name may be customizable.

Next steps

On this page