The /.github/workflows directory contains GitHub Actions workflows for continuous integration, deployment, and automation tasks.
Table of contents
Notes
- Workflows run on GitHub-hosted runners (
ubuntu-latest) or self-hosted runners ([self-hosted, windows]) depending on the task - Python workflows use Python 3.x on Ubuntu runners for documentation generation
- PowerShell workflows use PowerShell on Windows runners for application deployment
- Most workflows use concurrency groups to prevent duplicate runs and conserve resources
- Workflows are triggered by push events, pull requests, releases, or manual dispatch (
workflow_dispatch) - Several workflows interact with scripts in /scripts/README.md
Continuous Integration and Testing
Continuous Integration
Validates code quality, runs tests, and ensures the application builds correctly before merging changes.
Workflow properties
| Property | Value |
|---|---|
| Workflow | continuous-integration.yml |
| Trigger | Pull requests to main branch (opened, synchronize, reopened) |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | windows-latest (GitHub-hosted) |
| Concurrency | Group: ci-$, cancel-in-progress: true |
Jobs
- backend-validation - Validates PHP/Laravel backend
- Installs PHP 8.2+ with extensions (fileinfo, zip, sqlite3, pdo_sqlite, gd, exif)
- Validates
composer.jsonand checks platform requirements - Installs dependencies with
composer install - Audits dependencies for security vulnerabilities
- Creates
.envfile from.env.local.example - Runs database migrations (up and rollback tests)
- Lints code with Laravel Pint
- Runs test suites: CI/CD, Unit, and Feature tests with coverage
- frontend-validation - Validates Node.js/Vue frontend
- Installs Node.js lts\Krypton (24.x)
- Installs npm dependencies with
npm ci - Audits npm packages for vulnerabilities
- Builds frontend assets with
npm run build - Lints code with
npm run lint - Runs all tests with
npm run test:all
- ci-success - Aggregates results
- Checks that both backend and frontend validation jobs succeeded
- Fails the workflow if either validation job failed
Permissions
contents: write- For potential version bumpspull-requests: write- For PR comments and labelspackages: read- For accessing GitHub Packages
Usage
This workflow runs automatically on pull requests. For manual testing:
# Trigger via GitHub UI: Actions > Continuous Integration > Run workflow
Links
| Reference | URL |
|---|---|
| GitHub Actions workflow_dispatch | https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch |
Continuous Deployment
Deploy Laravel Application
Builds the Laravel application and deploys it to a production environment using a symlink-based deployment strategy.
Workflow properties
| Property | Value |
|---|---|
| Workflow | continuous-deployment.yml |
| Trigger | Push to main branch |
| Manual trigger | No |
| Runner | [self-hosted, windows] |
| Environment | MWNF-SVR |
Jobs
- build - Builds deployment package
- Validates environment variables and paths (PHP, Composer, Node.js, npm, MariaDB)
- Installs PHP dependencies with
composer install --no-dev --optimize-autoloader - Configures npm authentication for GitHub Packages
- Installs Node.js dependencies with
npm install - Builds frontend assets with Vite (
npm run build) - Creates deployment package excluding dev dependencies
- Generates
VERSIONfile with app version, commit SHA, and timestamps - Uploads deployment artifact (
laravel-app-$) with 7-day retention
- deploy - Deploys to staging directory with symlink swap
- Downloads deployment artifact
- Creates timestamped staging directory (
staging-YYYYMMDD-HHMMSS) - Puts old application into maintenance mode (
php artisan down) - Creates temporary symlink to new staging directory
- Atomically swaps symlinks to minimize downtime
- Cleans up obsolete staging directories (keeps last 3)
- Implements rollback capability if symlink swap fails
- configure - Configures Laravel application
- Generates production
.envfile from.env.exampleusing environment variables - Runs database migrations (
php artisan migrate --force) - Syncs permissions and roles (
php artisan permissions:sync --production) - Caches configuration, routes, and views for performance
- Generates production
Environment Variables (set in GitHub environment MWNF-SVR)
| Variable | Description | Default |
|---|---|---|
PHP_PATH |
Path to PHP executable | C:\Program Files\PHP\php.exe |
COMPOSER_PATH |
Path to Composer executable | C:\ProgramData\ComposerSetup\bin\composer.bat |
NODE_PATH |
Path to Node.js executable | C:\Program Files\nodejs\node.exe |
NPM_PATH |
Path to npm executable | C:\Program Files\nodejs\npm.ps1 |
MARIADB_PATH |
Path to MariaDB client | C:\Program Files\MariaDB 10.5\bin\mysql.exe |
DEPLOY_PATH |
Deployment base directory | C:\Apache24\htdocs\inventory-app |
WEBSERVER_PATH |
Symlink location for webserver | C:\Apache24\htdocs\inventory-app |
APP_NAME |
Application name | inventory-app |
APP_ENV |
Environment (production/staging) | production |
APP_DEBUG |
Enable debug mode | false |
APP_URL |
Application URL | http://localhost |
DB_CONNECTION |
Database driver | mysql |
DB_HOST |
Database host | 127.0.0.1 |
DB_PORT |
Database port | 3306 |
API_DOCS_ENABLED |
Enable API documentation | false |
APACHE_SERVICE_USER |
Apache service user | SYSTEM |
TRUSTED_PROXIES |
Comma-separated proxy IPs/CIDR | (empty) |
Environment Secrets (set in GitHub environment MWNF-SVR)
| Secret | Description |
|---|---|
APP_KEY |
Laravel application key (generate with php artisan key:generate --show) |
MARIADB_DATABASE |
Database name |
MARIADB_USER |
Database username |
MARIADB_SECRET |
Database password |
Deployment Strategy
This workflow uses a symlink-based zero-downtime deployment:
- Build artifact is downloaded to a timestamped staging directory
- Application is put into maintenance mode
- A temporary symlink is created pointing to the new staging directory
- The webserver symlink is atomically swapped to the new deployment
- Old symlinks are removed
- Old staging directories are cleaned up (keeps last 3 for rollback)
Permissions
contents: read- For reading repository contentspackages: read- For accessing GitHub Packages
Usage
This workflow runs automatically when changes are pushed to main.
Links
| Reference | URL |
|---|---|
| Laravel Deployment | https://laravel.com/docs/12.x/deployment |
| GitHub Environments | https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment |
Deploy Documentation to GitHub Pages
Generates and deploys the Jekyll-based static documentation website to GitHub Pages. This workflow calls Python scripts to generate commit history and API client documentation.
See /docs/README.md for complete Jekyll site documentation.
Workflow properties
| Property | Value |
|---|---|
| Workflow | continuous-deployment_github-pages.yml |
| Trigger | Push to main branch |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | ubuntu-latest (GitHub-hosted) |
| Concurrency | Group: pages-deploy, cancel-in-progress: true |
Jobs
- build - Generates and builds documentation
- Checks out repository with full Git history (
fetch-depth: 0) - Sets up Python 3.x
- Sets up Ruby 3.2.3
- Installs Ruby dependencies with
bundle install - Generates commit history documentation - Calls
python scripts/generate-commit-docs.py. See /scripts/README.md - Generates API client documentation - Calls
python scripts/generate-client-docs.py. See /scripts/README.md - Builds Jekyll site with
bundle exec jekyll build - Uploads artifact for GitHub Pages
- Checks out repository with full Git history (
- deploy - Deploys to GitHub Pages
- Uses
actions/deploy-pages@v4to publish the site - Sets environment to
github-pages - Outputs deployment URL
- Uses
Permissions
contents: read- For reading repository contentscontents: write- For committing generated documentation (build job)pages: write- For deploying to GitHub Pagesid-token: write- For GitHub Pages authentication
Scripts called
This workflow depends on the following scripts:
generate-commit-docs.py- Converts Git commit history into Jekyll markdown pages. See /scripts/README.mdgenerate-client-docs.py- Converts TypeScript API client docs into Jekyll markdown pages. See /scripts/README.md
For Jekyll site documentation, see /docs/README.md
Usage
This workflow runs automatically on push to main. For manual deployment:
# Trigger via GitHub UI: Actions > Continuous Deployment to GitHub Pages > Run workflow
Links
| Reference | URL |
|---|---|
| GitHub Pages | https://pages.github.com/ |
| Documentation Site | https://metanull.github.io/inventory-app |
| Jekyll Documentation | https://jekyllrb.com/docs/ |
Publish API Client Package
Publishes the TypeScript API client package to GitHub Packages when a release is created.
Workflow properties
| Property | Value |
|---|---|
| Workflow | publish-npm-github-package.yml |
| Trigger | Release created |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | ubuntu-latest (GitHub-hosted) |
Jobs
- build - Builds and tests the package
- Checks out repository
- Sets up Node.js 20
- Installs dependencies with
npm ci - Runs tests with
npm test
- publish-gpr - Publishes to GitHub Packages
- Checks out repository
- Sets up Node.js 20 with GitHub Packages registry
- Installs dependencies with
npm ci - Publishes package with
npm publish
Permissions
contents: read- For reading repository contentspackages: write- For publishing to GitHub Packages
Prerequisites
Before this workflow can run successfully:
- API client must be generated using
generate-api-client.ps1. See /scripts/README.md - Package version should be updated appropriately
- A release must be created in GitHub
Usage
This workflow runs automatically when a GitHub release is created. For manual publishing:
# Trigger via GitHub UI: Actions > Package @metanull/inventory-app-api-client > Run workflow
Alternatively, you can publish manually using the script:
# See: /scripts/README.md#publishing-the-api-client-npm-package-to-the-github-packages-npm-registry
. ./scripts/publish-api-client.ps1 -Credential (Get-Credential)
Links
| Reference | URL |
|---|---|
| GitHub Packages | https://github.com/features/packages |
| API Client Package | https://github.com/metanull/inventory-app/pkgs/npm/inventory-app-api-client |
| Publishing Node.js Packages | https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages |
Automation Workflows
Version Bump
Automatically bumps the project version based on merged pull request labels after successful CI runs.
Workflow properties
| Property | Value |
|---|---|
| Workflow | version-bump.yml |
| Trigger | After Continuous Integration workflow completes successfully on main |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | windows-latest (GitHub-hosted) |
| Concurrency | Group: version-bump-$, cancel-in-progress: true |
Job: version-bump
- Checks out repository with full Git history
- Sets up Node.js 20.x
- Checks if commit is already a version bump (skips if so)
- Retrieves merged PR information and labels
- Determines version bump type based on labels:
breaking-change→ major version bumpfeature→ minor version bumpbugfix→ patch version bump- Default: patch version bump
- Bumps version in
package.jsonusingnpm version - Commits and pushes version bump to
mainbranch
Permissions
contents: write- For committing version bumpspull-requests: read- For reading PR metadata
Usage
This workflow runs automatically after CI completes successfully. For manual version bumping:
# Trigger via GitHub UI: Actions > Version Bump > Run workflow
PR Labeling Guide
To control version bumping, apply these labels to your pull requests:
breaking-change- For breaking API changes (major version)feature- For new features (minor version)bugfix- For bug fixes (patch version)
Links
| Reference | URL |
|---|---|
| Semantic Versioning | https://semver.org/ |
| GitHub Actions workflow_run | https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run |
Dependabot Configuration
Dependabot is configured in .github/dependabot.yml to keep dependencies up to date for four ecosystems.
Ecosystems monitored
| Ecosystem | Directory | Schedule | Registry |
|---|---|---|---|
composer |
/ |
Weekly | packagist.org (public) |
npm |
/ |
Weekly | npm.pkg.github.com (GitHub) |
npm |
/spa |
Weekly | npm.pkg.github.com (GitHub) |
github-actions |
/ |
Weekly | github.com (public) |
GitHub Packages registry access
The npm ecosystems reference the GitHub Packages registry (npm.pkg.github.com), which requires authentication even for packages in the same organization. The registry token is configured as:
registries:
npm-github:
type: npm-registry
url: https://npm.pkg.github.com
token: $
Dependabot version updates run on Dependabot’s own infrastructure, not on GitHub Actions runners. This means the automatically provided GITHUB_TOKEN is not available as a secret in dependabot.yml. Instead, a Personal Access Token (PAT) must be stored as a Dependabot secret.
Note: The
$approach only works when “Dependabot on Actions runners” is enabled in the repository settings (Settings > Code security > Dependabot). This feature is not available on all GitHub plans and is not always accessible for free public repositories.
Setup instructions
- Create a Personal Access Token (classic) with
read:packagesscope - Store it as a Dependabot secret (not a regular Actions secret) named
DEPENDABOT_GITHUB_PACKAGES_TOKENunder Settings > Secrets and variables > Dependabot
Note: Dependabot secrets (under the Dependabot tab) are separate from Actions secrets (under the Actions tab). A secret in the Actions tab is not accessible to Dependabot.
Links
| Reference | URL |
|---|---|
| Dependabot configuration options | https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file |
| Dependabot on Actions runners | https://docs.github.com/en/code-security/dependabot/working-with-dependabot/about-dependabot-on-github-actions-runners |
| Configuring access to private registries | https://docs.github.com/en/code-security/dependabot/working-with-dependabot/configuring-access-to-private-registries-for-dependabot |
Merge Dependabot PR
Automatically approves and enables auto-merge for Dependabot pull requests that are not major version updates.
Workflow properties
| Property | Value |
|---|---|
| Workflow | merge-dependabot-pr.yml |
| Trigger | pull_request_target (any PR opened) |
| Manual trigger | No |
| Runner | ubuntu-latest (GitHub-hosted) |
| Condition | Only runs if PR author is dependabot[bot] |
Job: dependabot
- Fetches Dependabot PR metadata using
dependabot/fetch-metadataaction - Checks if update type is not a major version update
- Approves the PR using
gh pr review --approve - Enables auto-merge on the PR
Permissions
pull-requests: write- For approving and merging PRscontents: write- For merging changes
Behavior
- Minor and patch updates: Automatically approved and enabled for auto-merge
- Major updates: Require manual review (not auto-approved)
Usage
This workflow runs automatically when Dependabot opens a pull request. No manual intervention needed for minor/patch updates.
Links
| Reference | URL |
|---|---|
| Dependabot | https://docs.github.com/en/code-security/dependabot |
| dependabot/fetch-metadata | https://github.com/dependabot/fetch-metadata |
Workflow Dependencies
Several workflows interact with scripts and other workflows:
| Workflow | Depends On | Triggers |
|---|---|---|
continuous-integration.yml |
- | version-bump.yml |
continuous-deployment.yml |
- | - |
continuous-deployment_github-pages.yml |
/scripts/README.md scripts | - |
publish-npm-github-package.yml |
API client generation | - |
version-bump.yml |
continuous-integration.yml |
- |
merge-dependabot-pr.yml |
- | - |
Scripts used by workflows:
generate-commit-docs.py- Used bycontinuous-deployment_github-pages.yml. See /scripts/README.mdgenerate-client-docs.py- Used bycontinuous-deployment_github-pages.yml. See /scripts/README.md
Contributing
When adding new workflows:
- Add description to this README
- Document triggers, jobs, permissions, and environment variables
- Update the workflow dependencies table
- Add cross-references to /scripts/README.md if applicable
- Test both manual and automated execution
- Validate workflow syntax with
node scripts/validate-workflows.cjs. See /scripts/README.md