Complete GitFlow-based CI/CD pipeline for Ignition SCADA projects using GitHub Actions.
git@github.com:Mustry-Solutions/ignition-83-cicd.git
This repository implements a complete GitFlow workflow with automated deployments to multiple Ignition environments:
- Development (dev): Auto-deploys from
developbranch - Staging: Auto-deploys from
release/*branches - Production: Auto-deploys from tags on
mainbranch (e.g.,v1.0.0)
.
├── .github/
│ └── workflows/
│ ├── ci-cd.yml # Main CI/CD pipeline
│ └── promote-release.yml # Release promotion pipeline
├── docker-compose.yml # Multi-environment Docker setup
├── projects/
│ └── example-project/ # Ignition projects
│ ├── project.json
│ ├── com.inductiveautomation.perspective/
│ └── ignition/script-python/
├── config/
│ └── environments/ # Environment-specific configs
│ ├── dev.yaml
│ ├── staging.yaml
│ └── prod.yaml
├── scripts/
│ ├── deploy.sh # Main deployment script
│ ├── backup-gateway.sh # Gateway backup
│ ├── restore-gateway.sh # Gateway restore
│ ├── deploy-project.sh # Deploy individual project
│ ├── package-project.sh # Package project as ZIP
│ ├── db-migrate.sh # Database migrations
│ ├── db-rollback.sh # Database rollback
│ ├── validate-names.sh # Linting and validation
│ └── smoke-test.sh # Smoke tests
├── migrations/ # Database migration files
└── backups/ # Gateway backups
├── dev/
├── staging/
└── prod/
docker-compose up -dThis starts three Ignition gateways:
- Dev: http://localhost:8088 (admin/Test123!)
- Staging: http://localhost:8188 (admin/Test123!)
- Production: http://localhost:8288 (admin/Test123!)
Plus a PostgreSQL database on port 5432.
# Package a project
./scripts/package-project.sh projects/example-project
# Deploy to development
./scripts/deploy.sh dev# Apply all migrations to dev
./scripts/db-migrate.sh dev up
# Check current version
./scripts/db-migrate.sh dev versionfeature/* → develop → release/* → main
↓
tags (v1.0.0)
| Branch Type | Purpose | Environment | Auto-Deploy |
|---|---|---|---|
develop |
Integration & QA | Development | Yes |
release/* |
UAT & Stabilization | Staging | Yes |
main + tag |
Production code | Production | Yes (on tag) |
feature/* |
Feature development | Local | No |
hotfix/* |
Critical fixes | Production | Yes (via tag) |
-
Create feature branch:
git checkout develop git pull origin develop git checkout -b feature/my-new-feature
-
Develop and commit:
# Make changes to projects/ git add . git commit -m "Add new feature" git push origin feature/my-new-feature
-
Create Pull Request to
develop:- CI pipeline validates and builds
- After merge, auto-deploys to Development
-
Create release branch:
git checkout develop git pull origin develop git checkout -b release/1.0.0 git push origin release/1.0.0
- Auto-deploys to Staging
- Run UAT and testing
-
Promote to production:
- Option A: Use promote-release pipeline (manual)
- Option B: Create tag manually:
git checkout main git merge release/1.0.0 --no-ff git tag -a v1.0.0 -m "Release version 1.0.0" git push origin main --tags - Auto-deploys to Production
- GitHub Repository: Mustry-Solutions/ignition-83-cicd
- GitHub Actions: Enabled by default
- Secrets: Configure in repository settings for sensitive credentials
This is automatically triggered on:
- Push to
develop,release/*,main - Tags matching
v* - Pull requests
Manually triggered workflow to promote releases:
- Go to Actions → Promote Release
- Click "Run workflow"
- Enter release branch (e.g.,
release/1.0.0) - Enter tag (e.g.,
v1.0.0) - Choose whether to merge to main
- Click "Run workflow"
Configure these in Settings → Secrets and variables → Actions:
DEV_GATEWAY_URL: http://localhost:8088DEV_GATEWAY_USER: adminDEV_GATEWAY_PASS: Test123!DEV_GATEWAY_API_KEY: API token with config/project scan accessDEV_DB_URL: postgres://ignition:@localhost:5432/ignition_dev?sslmode=disable
STAGING_GATEWAY_URL: http://localhost:8188STAGING_GATEWAY_USER: adminSTAGING_GATEWAY_PASS: Test123!STAGING_GATEWAY_API_KEY: API token with config/project scan accessSTAGING_DB_URL: postgres://ignition:ignition-db-password@localhost:5432/ignition_staging?sslmode=disable
PROD_GATEWAY_URL: http://localhost:8288PROD_GATEWAY_USER: adminPROD_GATEWAY_PASS: Test123!PROD_GATEWAY_API_KEY: API token with config/project scan accessPROD_DB_URL: postgres://ignition:ignition-db-password@localhost:5432/ignition_prod?sslmode=disable
Note: Use GitHub Environments and Secrets for secure credential management.
- Do not commit passwords or API keys in
config/environments/*.yaml. - Copy
.env.exampleto.env.localand set local values. - Optional local fallback: put only the API token in
secrets/gateway_api_key(used when*_GATEWAY_API_KEYis not set). ignition-localnow persists the full gateway data directory in the Docker named volumeignition-local-data, so local commissioning/auth/runtime state is retained outside version control.- Local commissioning uses Docker-image environment variables (
GATEWAY_ADMIN_USERNAMEandGATEWAY_ADMIN_PASSWORD). - Keep
GATEWAY_ADMIN_PASSWORDset in your local environment so a fresh local gateway can completeauthSetupwithout manual/welcomeuser creation. secrets/is local-only and gitignored (.gitignore), so this is acceptable for local Docker development.- In CI/CD, always use GitHub Environment Secrets (or an external secrets manager), not files in the repo.
- Load variables before running scripts locally:
set -a
source .env.local
set +a- Go to Settings → Environments
- Create three environments:
development(no approval required)staging(optional approval)production(approval required)
- Add secrets to each environment as needed
- For production, configure required reviewers under environment protection rules
Using golang-migrate for database versioning.
# Using migrate CLI (if installed)
migrate create -ext sql -dir migrations -seq add_new_table
# Or manually create:
# migrations/000003_add_new_table.up.sql
# migrations/000003_add_new_table.down.sql# Apply all pending migrations
./scripts/db-migrate.sh dev up
# Rollback last migration
./scripts/db-migrate.sh dev down
# Go to specific version
./scripts/db-migrate.sh dev goto 2
# Check current version
./scripts/db-migrate.sh dev version./scripts/db-rollback.sh staging 5This ensures the database stays in a good state after rollback.
Code style requirements:
- Files: camelCase
- Functions: camelCase
- Variables: camelCase
- Indentation: tabs (not spaces)
- No print statements in Python code
- Perspective components: PascalCase
- Component properties: camelCase
./scripts/validate-names.sh projects/This is automatically run in the CI pipeline.
./scripts/backup-gateway.sh prodBackups are stored in backups/<environment>/ and automatically cleaned up based on retention policy.
./scripts/restore-gateway.sh prod ./backups/prod/gateway_backup_prod_20240101_120000.gwbk# Start only development
docker-compose up -d ignition-dev
# Start dev and staging
docker-compose up -d ignition-dev ignition-staging# All services
docker-compose logs -f
# Specific environment
docker-compose logs -f ignition-devdocker-compose down# Stop and remove everything including volumes
docker-compose down -v
# Restart
docker-compose up -d./scripts/smoke-test.sh dev
./scripts/smoke-test.sh staging
./scripts/smoke-test.sh prodAccess the gateways at:
- Dev: http://localhost:8088/web/home
- Staging: http://localhost:8188/web/home
- Production: http://localhost:8288/web/home
-
Create project directory:
mkdir -p projects/my-new-project
-
Add project files following Ignition structure:
projects/my-new-project/ ├── project.json ├── com.inductiveautomation.perspective/ │ └── views/ └── ignition/ └── script-python/ -
Commit and push:
git add projects/my-new-project git commit -m "Add new project: my-new-project" git push -
CI pipeline will automatically package and deploy
Follow Ignition 8.3 project structure:
project.json: Project metadatacom.inductiveautomation.perspective/: Perspective views and componentsignition/script-python/: Python script modulesignition/named-query/: Named queriesignition/tags/: Tag definitions
# Check container status
docker-compose ps
# View logs
docker-compose logs ignition-dev
# Restart gateway
docker-compose restart ignition-dev# Check PostgreSQL is running
docker-compose ps postgres
# Connect to database
docker exec -it ignition-postgres psql -U ignition -d ignition-
Check gateway is healthy:
curl http://localhost:8088/StatusPing
-
Verify credentials in config files
-
Check deployment logs in Azure DevOps pipeline
# Check current version
./scripts/db-migrate.sh dev version
# Force to specific version
./scripts/db-migrate.sh dev goto 1Modify config/environments/<env>.yaml to add custom deployment steps:
deployment:
pre_deploy_scripts:
- db_migrate
- custom_validation
post_deploy_scripts:
- smoke_test
- notify_teamEach environment has its own configuration file in config/environments/:
- Gateway URL and credentials
- Database connection
- Backup retention policy
- Deployment scripts
- Ignition 8.3 Docker Documentation
- Ignition Version Control Guide
- Golang Migrate Documentation
- GitFlow Workflow
For issues or questions:
- Check this README
- Review Azure DevOps pipeline logs
- Check container logs:
docker-compose logs - Contact DevOps team