@cdwr/nx-pre-deploy-action
v0.0.2
Published
The Nx Pre-deploy Action will analyze the applications to deploy and to which environment.
Downloads
61
Readme
Description
This action performs pre-deployment analysis for applications in an Nx workspace.
- Determines the deployment environment based on the GitHub event
- Analyzes which Nx applications that should be deployed
- Optionally fetches app-tenant relations and secrets from Infisical for multi-tenant deployments
This action is intended to be used before the Fly Deployment Action.
[!NOTE] Deployment architecture and configuration overview How this action fits in the workflow.
See: DEPLOYMENT.md
Features
Environment Detection
Automatically determines whether to deploy to preview or production based on:
- Pull requests →
previewenvironment - Push to main branch →
productionenvironment - Fallback to empty environment, which should indicate a deployment can't be performed
Returned in environment output.
Affected Apps Analysis
Uses Nx to determine which applications have been affected by code changes and should be deployed.
Returned in apps output.
Multi-tenant Support
Optionally fetches tenant secrets from Infisical to enable multi-tenant deployments with per-tenant environment variables and secrets:
- Reads
DEPLOY_RULESsecret to determine which apps and tenants are allowed to be deployed for each environment - Discovers tenant-app relationships from Infisical folder structure:
→/tenants/<tenant-id>/apps/<app-name>/ - Classifies secrets as environment variables (public, visible) or secrets (encrypted, hidden) using Infisical secret metadata:
→ setenvkey totruefor public secrets - Each affected application is deployed once per tenant with isolated configuration when available
Returned in app-tenant output.
[!NOTE] Deployment flow diagrams and architecture See: DEPLOYMENT.md
Usage
Basic Usage (without tenants)
jobs:
pre-deploy:
runs-on: ubuntu-latest
outputs:
apps: ${{ steps.pre-deploy.outputs.apps }}
environment: ${{ steps.pre-deploy.outputs.environment }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build pre-deploy action
run: pnpm nx build nx-pre-deploy-action
- name: Run pre-deploy
id: pre-deploy
uses: ./packages/nx-pre-deploy-action
fly-deployment:
if: ${{ needs.pre-deploy.outputs.environment != '' }}
needs: pre-deploy
runs-on: ubuntu-latest
environment: ${{ needs.pre-deploy.outputs.environment }}
steps:
# ... deployment stepsMulti-tenant Usage (with Infisical)
jobs:
pre-deploy:
runs-on: ubuntu-latest
outputs:
environment: ${{ steps.pre-deploy.outputs.environment }}
app-tenants: ${{ steps.pre-deploy.outputs.app-tenants }}
steps:
# ... install steps
- name: Run pre-deploy
id: pre-deploy
uses: ./packages/nx-pre-deploy-action
with:
infisical-client-id: ${{ secrets.CLIENT_ID }}
infisical-client-secret: ${{ secrets.CLIENT_SECRET }}
infisical-project-id: ${{ secrets.PROJECT_ID }}
fly-deployment:
if: ${{ needs.pre-deploy.outputs.environment != '' }}
needs: pre-deploy
runs-on: ubuntu-latest
environment: ${{ needs.pre-deploy.outputs.environment }}
steps:
# app-tenants is compatible with app-details,
# but with a stricter type
- name: Deploy
uses: ./packages/nx-fly-deployment-action
with:
app-details: ${{ needs.pre-deploy.outputs.app-tenants }}
# ... other inputsInputs
| Input | Description | Required | Default |
| ------------------------- | ------------------------------------ | -------- | ------------------------- |
| main-branch | The main branch name | No | Repository default branch |
| token | GitHub token for authentication | No | GITHUB_TOKEN |
| infisical-client-id | Infisical machine client ID | No | - |
| infisical-client-secret | Infisical machine client secret | No | - |
| infisical-project-id | Infisical project ID | No | - |
| infisical-site | Infisical site to use (eu or us) | No | eu |
Outputs
| Output | Description | Example |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| apps | List of applications to deploy | api,cms,web |
| environment | Deployment environment that match the GitHub event, if any. | preview, production or empty string |
| app-tenants | JSON object mapping multi-tenant apps to their tenants deployment details. Each app maps to an array with tenant, env, and secrets for per-tenant configuration. | See example below where api has no tenancy, cms has one tenant without secrets and web both exposed and hidden secrets |
// apps:
"api,cms,web"
// app-tenants:
{
// 'api' left out
"cms": [{ "tenant": "acme" }],
"web": [
{
"tenant": "acme",
"env": { "PUBLIC_URL": "..." },
"secrets": { "API_KEY": "..." }
}
]
}Environment Variables
The action sets environment variables that can be used in subsequent workflow steps:
DEPLOY_ENV: Same as theenvironmentoutput
Multi-tenant Setup
To enable multi-tenant deployments with per-tenant configuration:
1. Infisical Folder Structure
Store secrets in Infisical using this structure:
// applications with their secrets
/apps/<app-name>/<SECRET_NAME>
// tenants with their secrets !! MUST TEST THIS !!
/tenants/<tenant-id>/<SECRET_NAME>
// applications to deploy for each tenant with
// app-specific secrets
/tenants/<tenant-id>/apps/<app-name>/<SECRET_NAME>Example:
- Applications:
api,web - Tenants:
acme,globex
web is a multi-tenant application deployed for both tenants.
/apps/api/PUBLIC_URL = "https://api.example.com"
/apps/web/PUBLIC_URL = "https://web.example.com"
/tenants/acme/apps/web/PUBLIC_URL = "https://acme.example.com"
/tenants/acme/apps/web/API_KEY = "sk_acme*"
/tenants/globex/apps/web/PUBLIC_URL = "https://globex.example.com"
/tenants/globex/apps/web/API_KEY = "sk_globex*"2. Classify Secrets vs Environment Variables
Use Infisical's secret metadata to control whether values are treated as environment variables (visible) or secrets (encrypted):
- Environment Variable (public, visible): Set metadata key
envtotrue - Secret (encrypted, hidden): Don't set the metadata, or set
envtofalse
Secure by default: Everything is treated as a secret unless explicitly marked as an environment variable.
[!NOTE] Understanding deployment-time vs runtime secret loading
3. Deploy rules
Create DEPLOY_RULES secret in the root path and add rules for each environment.
This way it's possible to have full multi-tenant deployments in production, but only a subset of apps and tenants in preview.
Rules can be specified in two ways:
Option 1: Metadata (preferred)
Add rules as secret metadata with apps and tenants keys. Infisical UI has native support for metadata, but it's only visible from secret details.
Option 2: JSON secret value (fallback)
Add rules as secret value in JSON format:
{
apps: string;
tenants: string;
}Example: { "apps": "*", "tenants": "*" }
Use this when you rather want to see the rules in the secrets list.
[!IMPORTANT] Either way, the rules must be valid otherwise an error is thrown
Rules format examples:
apps: '*' # all apps
apps: 'web,cms' # only web and cms apps
tenants: '*' # all discovered tenants
tenants: 'demo' # only demo tenant
tenants: 'demo,acme' # only demo and acme tenants4. Provide Infisical Credentials
Add Infisical client ID, client secret and project ID as GitHub secrets. Use them for corresponding action inputs.
