Reusable GitHub Actions CI/CD framework for Next.js projects with multi-environment deployments, semantic versioning, and comprehensive testing.
- Multi-environment deployments — Production, release, and sandbox/preview environments
- Semantic versioning — Auto-increment via PR markers (
[major],[minor],[patch]) - SFTP deployment — Backup, deploy, verify, and symlink management
- Testing pipeline — ESLint, TypeScript, Cucumber BDD, Playwright E2E
- Smart skip logic — Bypass tests for
ci:,chore:,docs:commits - PR previews — Auto-deploy feature branches with comment notifications
- GitHub releases — Auto-generated changelogs from git history
Copy the workflows from starter-workflows/ to your repository's .github/workflows/:
# In your project
mkdir -p .github/workflows
curl -o .github/workflows/release.yml https://raw.githubusercontent.com/ursine-code/static-deploy-kit/main/starter-workflows/release.yml
curl -o .github/workflows/feature-branch.yml https://raw.githubusercontent.com/ursine-code/static-deploy-kit/main/starter-workflows/feature-branch.ymlUpdate ursine-code with the actual GitHub username/org hosting this repo:
sed -i 's/ursine-code/your-github-username/g' .github/workflows/*.ymlAdd required secrets to your repository (see Configuration).
static-deploy-kit/
├── .github/
│ ├── actions/ # Reusable composite actions
│ │ ├── setup-node-pnpm/
│ │ ├── build-project/
│ │ ├── typecheck/
│ │ ├── bdd-tests/
│ │ ├── create-git-tag/
│ │ ├── prepare-git-tag/
│ │ ├── configure-deployment/
│ │ ├── deploy-to-remote-server/
│ │ └── create-github-release/
│ └── workflows/ # Reusable workflows
│ ├── e2e.yml
│ └── dry-run.yml
└── starter-workflows/ # Copy these to your repo
├── release.yml
└── feature-branch.yml
Reference actions in your workflows:
steps:
- uses: ursine-code/static-deploy-kit/.github/actions/setup-node-pnpm@main
- uses: ursine-code/static-deploy-kit/.github/actions/build-project@main
with:
artifact-name: 'build-files'Call reusable workflows:
jobs:
e2e:
uses: ursine-code/static-deploy-kit/.github/workflows/e2e.yml@main
with:
environment: 'production'
secrets: inheritInclude version marker in PR title or body:
feat: add user dashboard [minor]
Supported markers: [major], [minor], [patch], #major, #minor, #patch
Trigger release.yml via workflow_dispatch:
deployment_type: manual_tag_deploy
tag_to_deploy: v2.0.0
create_github_release: true
deploy_target: latestPRs automatically deploy to sandboxes/{branch-name}/ with preview URL posted as comment.
| Secret | Description |
|---|---|
SFTP_HOST |
Remote server hostname |
SFTP_USERNAME |
SFTP username |
SFTP_PASSWORD |
SFTP password |
DEPLOY_BASE_PATH |
Base path (e.g., /home/user/domain.com) |
PRODUCTION_DOMAIN |
Production domain (e.g., example.com) |
SANDBOX_DOMAIN |
Sandbox domain (optional) |
Set in workflow or repository settings:
NODE_VERSION: '20.18.0'
PNPM_VERSION: '10.18.1'/deploy-path/
├── latest/ # Symlink → most recent release
├── releases/
│ ├── v1.0.0/
│ ├── v1.1.0/
│ └── v2.0.0/
└── sandboxes/
├── feature-auth/
└── fix-header/
Add [DEBUG_DEPLOYMENT_INFORMATION] to commit message for verbose logging.
- Node.js 20+
- pnpm
- Next.js with
output: "export" - SFTP-accessible deployment server
Use @main for latest, or pin to a specific tag:
uses: ursine-code/static-deploy-kit/.github/actions/build-project@v1.0.0MIT