Official GitHub Actions for deploying apps to the Norce Base Platform.
| Action | Purpose |
|---|---|
deploy |
Deploy an image tag to any named environment |
pr |
Create, update, and delete per-PR preview environments |
promote |
Promote a staged canary to live, or copy an image between environments |
sync-secrets |
Push GitHub secret values to the platform vault |
- Get your partner API key from the Base Portal (or from your NorceTech contact)
- Add it as a repository secret named
BASE_PLATFORM_API_KEY
The API key identifies your partner — there's no need to pass the partner name in your workflows.
These actions parse your .base/*.yaml files with yq,
falling back to python3 + PyYAML. GitHub-hosted runners ship yq preinstalled, so
nothing is needed there. On a self-hosted runner, make sure one of the two is present
on the image, or install yq in a step before the action:
- name: Ensure yq is available
run: |
set -euo pipefail
command -v yq >/dev/null && exit 0
# Pick the asset for THIS runner — an amd64 binary on an arm64 runner
# fails with a confusing "cannot execute binary file".
case "$(uname -m)" in
x86_64) YQ_ARCH=amd64 ;;
aarch64|arm64) YQ_ARCH=arm64 ;;
*) echo "unsupported arch $(uname -m)"; exit 1 ;;
esac
mkdir -p "$RUNNER_TEMP/bin"
curl -fsSL -o "$RUNNER_TEMP/bin/yq" \
"https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${YQ_ARCH}"
chmod +x "$RUNNER_TEMP/bin/yq"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"For anything beyond a stopgap, pin the release and verify it — this step puts an
executable on PATH for every later step in the job. Pin yq_linux_<arch> to a
tagged version and check it against the SHA-256 column of that release's
checksums asset before chmod +x.
If neither is available the action now stops with an explicit error naming what is
missing. Before v1.1.2 it exited 1 with an empty log.
name: Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.build.outputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Build and push
id: build
run: echo "tag=${{ github.sha }}" >> $GITHUB_OUTPUT
deploy-stage:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { sparse-checkout: .base }
- uses: NorceTech/base-actions/deploy@v1
with:
environment: stage
image_tag: ${{ needs.build.outputs.image_tag }}
api_key: ${{ secrets.BASE_PLATFORM_API_KEY }}See the deploy action docs for the full picture.
Named environments — created by you in the portal:
| Suggested name | Typical use |
|---|---|
dev |
Local / developer testing |
test |
Integration testing |
stage |
Pre-production testing |
prod |
Live production |
You can create environments with any name you like — brand-a-prod, eu-stage, demo, etc.
PR environments — ephemeral, one per PR, auto-created and auto-deleted:
pr-*, preview-*, feature-*, branch-*
All optional. Place them in .base/ at the repo root:
| File | Purpose | Docs |
|---|---|---|
.base/config.yaml |
Per-environment config (replicas, resources, env vars, autoscaling) | docs/config.md |
.base/secrets.yaml |
Which secrets each environment uses | docs/secrets.md |
.base/nginx.yaml |
Custom proxy directives (headers, buffers, redirects) | docs/nginx.md |
.base/redirects.yaml or .csv |
Bulk URL redirects (migrations, SEO) | docs/nginx.md |
- Configuration reference —
.base/config.yamlkeys, PR templates, internal-only apps - Autoscaling — triggers (CPU, memory, HTTP, cron), behavior presets, scale-to-zero
- Secrets —
.base/secrets.yaml, scope tags, staged-deploy overrides - Proxy config & redirects — custom snippets, bulk URL redirects
- Multi-brand deploys — run multiple sites from a single app
Custom domains are managed in the Base Portal (Settings → Domains). When you add one, the platform automatically:
- Issues an HTTPS certificate
- Configures traffic routing
No workflow changes needed when adding or removing custom domains. HTTP-based autoscaling counts traffic from every domain (internal and custom) against the same environment.
- Your workflow calls the action with deployment parameters
- The action reads
.base/*.yamlfrom the runner's working directory - The action calls the Base Platform API (partner is identified by the API key)
- The platform applies the configuration to your environment
- The action polls for health status (when
wait_for_healthy: true, the default fordeploy)
Partners also have a dedicated configuration repository for advanced overrides and custom manifests. Reach out to NorceTech if you need access.