Shared GitHub Actions workflows, composite actions, and organisation defaults for all VeamStudios repositories.
Selects a specific Xcode installation on macOS runners.
- uses: VeamStudios/.github/.github/actions/select-xcode@main
# with:
# xcode-version: "26.3" # defaultInstalls Node.js and configures npm/yarn to authenticate with the @veamstudios GitHub Packages registry. Works with both npm ci and yarn publish.
- uses: VeamStudios/.github/.github/actions/setup-node-github-packages@main
# with:
# node-version: "24.x" # default
# cache: "npm" # or "yarn"Writes the App Store Connect API key .p8 file to the filesystem for Fastlane and xcodebuild.
- uses: VeamStudios/.github/.github/actions/setup-asc-api-key@main
with:
key-id: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
key-content: ${{ secrets.APP_STORE_CONNECT_API_KEY_CONTENT }}All reusable workflows are called with uses: at the job level.
Full CI pipeline for web apps: format check, lint, typecheck, and build.
jobs:
ci:
uses: VeamStudios/.github/.github/workflows/web-ci.yml@main
# with:
# node_version: "24.x" # default
# build_command: "build" # defaultChecks whether any PRs were merged to a branch within a time window. Used by nightly deploy workflows to skip builds when nothing changed.
jobs:
check:
uses: VeamStudios/.github/.github/workflows/merge-gate.yml@main
permissions:
pull-requests: read
# with:
# base_branch: "main" # default
# window_hours: 24 # defaultOutput: should_deploy ("true" / "false")
Mints a Release Bot token and creates a GitHub release with optional auto-generated notes.
jobs:
release:
uses: VeamStudios/.github/.github/workflows/create-github-release.yml@main
with:
version: ${{ inputs.version }}
deploy_sha: ${{ needs.deploy.outputs.commit_sha }}
environment: prod
secrets:
BOT_RELEASE_PRIVATE_KEY: ${{ secrets.BOT_RELEASE_PRIVATE_KEY }}Outputs: release_url, tag_name
Sends a Slack notification to the releases channel. Optionally checks out changelog_git_ref and excerpts the matching section from CHANGELOG.md (same repo as the caller) so Slack shows per-release notes plus links to the repository and GitHub release.
jobs:
notify:
uses: VeamStudios/.github/.github/workflows/notify-release.yml@main
with:
version: v${{ inputs.version }}
environment: production
changelog_git_ref: ${{ needs.deploy.outputs.commit_sha }}
secrets:
SLACK_RELEASES_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }}changelog_git_ref— set to the deployed commit (or other ref) soCHANGELOG.mdat that SHA is used. When empty, only the genericslack_footer_mrkdwnline is sent.slack_footer_mrkdwn— used when the changelog is missing or has no##section for the version.
Polls App Store Connect for GitHub releases marked with <!-- veamstudios:app-store-live-monitor:pending ... --> and sends a short Slack notification once the matching App Store version is live.
jobs:
monitor:
uses: VeamStudios/.github/.github/workflows/ios-app-store-live-monitor.yml@main
with:
bundle_id: com.veamstudios.example
secrets: inheritrelease_tag— optional; when empty, recent releases are scanned for pending monitor markers.release_limit— number of recent releases to scan whenrelease_tagis empty. Defaults to20.live_states— App Store Connect states treated as live. Defaults toREADY_FOR_DISTRIBUTION,READY_FOR_SALE.dry_run— checks state without sending Slack or replacing the release marker.launch_hub_product— optional product slug,ciporsap. When set, a newly notified live App Store release also writesiOS Release Status,Last Production Sync, andProduction Evidenceto Launch Hub.launch_hub_product_page_id— optional Notion Product page ID override for unusual cases.
Mirrors production reality into Launch Hub Work Items. It writes exact production Remote Config values such as missing, false, research-preview, true, or any other live Firebase string, plus no platform key when a Work Item has no Remote Config key for that platform. It also mirrors production deployment/release evidence. It does not block deploys or decide whether a feature should be enabled.
jobs:
sync-launch-hub:
uses: VeamStudios/.github/.github/workflows/launch-hub-production-mirror.yml@main
with:
product: cip
platform: web
production_state: Deployed
production_evidence: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
firebase_project_id: checklistinspectorpro
github_environment: prod
secrets: inheritproduct— product slug used to filter Launch Hub Work Items. Supported values arecipandsap.product_page_id— optional Notion Product page ID override.platform— one ofios,web,android,backend, orall; deployment/release status writes only apply toios,web, andandroid.backendandallrefresh Remote Config values only.firebase_project_id— optional production Firebase project ID. When set withSERVICE_ACCOUNT_BASE64, the workflow reads the production Remote Config template and writes exact values to theiOS Prod RC Value,Web Prod RC Value, andAndroid Prod RC Valueselect fields. A configured key absent from Firebase is written asmissing; a blank platform key is written asno platform key.github_environment— optional GitHub environment name, such asprod, used whenSERVICE_ACCOUNT_BASE64is scoped to a deployment environment.production_stateandproduction_evidence— optional deployment/release mirror inputs.production_statewrites toiOS Release Status,Web Deploy Status, orAndroid Release Statusbased onplatform;production_evidenceis written only when one of those status fields is written.production_version— deprecated and ignored. Launch Hub no longer stores a shared production version.dry_run— prints the planned updates without changing Notion.
Copies a CHANGELOG.md from the caller repo to a marketing website repo.
jobs:
changelog:
uses: VeamStudios/.github/.github/workflows/update-changelog-website.yml@main
with:
source_file: CHANGELOG.md
deployed_ref: ${{ needs.deploy.outputs.commit_sha }}
destination_repo: VeamStudios/example.com
destination_folder: src/assets/changelog
version: v${{ inputs.version }}
secrets: inheritRuns tests for a Node-based repo. Pairs with web-ci.yml (which does lint/typecheck/build).
jobs:
tests:
uses: VeamStudios/.github/.github/workflows/web-tests.yml@main
# with:
# node_version: "24.x"
# test_command: "test"
# coverage_artifact_path: "coverage"Runs xcodebuild test on a scheme against a simulator destination. Uses the Release Bot App for SwiftPM private deps, same as pr-ios-build.yml.
jobs:
tests:
uses: VeamStudios/.github/.github/workflows/ios-tests.yml@main
with:
scheme: "SiteAuditPro"
project: "SiteAuditPro.xcodeproj"
secrets:
BOT_RELEASE_PRIVATE_KEY: ${{ secrets.BOT_RELEASE_PRIVATE_KEY }}Blocks PRs that add known-vulnerable packages (GHSA advisories) or disallowed licenses. Thin wrapper around actions/dependency-review-action.
jobs:
review:
uses: VeamStudios/.github/.github/workflows/dependency-review.yml@main
with:
fail_on_severity: highMarks inactive issues/PRs as stale and eventually closes them. Schedule from the caller (daily cron is typical). Label keep-open exempts an item from the sweep.
jobs:
stale:
uses: VeamStudios/.github/.github/workflows/stale.yml@mainRequests reviewers (users and/or teams) the moment a PR opens or is marked ready. Complements CODEOWNERS.
jobs:
assign:
uses: VeamStudios/.github/.github/workflows/auto-assign-reviewers.yml@main
with:
reviewers: "alice,bob,carol"
team_reviewers: "ios"| Workflow | Purpose |
|---|---|
deploy-ios-testflight.yml |
Build and upload an iOS app to TestFlight |
hotfix-prepare.yml / hotfix-deploy.yml |
iOS hotfix branch and deploy flow |
ios-app-store-live-monitor.yml |
Poll App Store Connect and notify Slack once a marked iOS release is live |
launch-hub-production-mirror.yml |
Mirror production Remote Config values and deployment/release state into Launch Hub |
pr-ios-build.yml |
Build iOS app on pull requests |
pr-spm-package-update.yml |
Auto-update SPM package dependencies |
qa-pipeline.yml |
Has Linked Notion Work Item on PR open/update (WI URL required when PR title starts with feat:); QA brief on bot: qa needed independent of the WI gate |
issue-cursor-agent.yml |
Triage GitHub issues with an AI agent |
The caller-templates/ directory contains example workflow files that repos can copy to adopt shared workflows quickly.
| Repo | Templates to copy |
|---|---|
ChecklistInspectorPro-iOS |
qa.yml, checklistinspectorpro-ios-tests.yml, dependency-review.yml, stale.yml, auto-assign-reviewers.yml |
ChecklistInspectorPro-Web |
qa.yml, web-ci.yml, web-tests.yml, dependency-review.yml, stale.yml, auto-assign-reviewers.yml |
ChecklistInspectorPro-Backend |
qa.yml, web-tests.yml (if Node), dependency-review.yml, stale.yml, auto-assign-reviewers.yml |
SiteAuditPro-iOS |
qa.yml, siteauditpro-ios-tests.yml, dependency-review.yml, stale.yml, auto-assign-reviewers.yml |
SiteAuditPro-Web |
qa.yml, web-ci.yml, web-tests.yml, dependency-review.yml, stale.yml, auto-assign-reviewers.yml |
SiteAuditPro-Backend |
qa.yml, web-tests.yml (if Node), dependency-review.yml, stale.yml, auto-assign-reviewers.yml |
The new templates rely on secrets already configured at the org or repo level:
| Template | Secrets | Notes |
|---|---|---|
qa.yml |
BOT_QA_PRIVATE_KEY, org vars.BOT_QA_CLIENT_ID |
Caller for qa-pipeline.yml |
web-tests.yml |
none beyond GITHUB_TOKEN |
packages: read is granted by the caller |
ios-tests.yml |
BOT_RELEASE_PRIVATE_KEY, org vars.BOT_RELEASE_CLIENT_ID |
Same Release Bot App used by pr-ios-build.yml |
launch-hub-production-mirror.yml |
NOTION_TOKEN, SERVICE_ACCOUNT_BASE64 |
SERVICE_ACCOUNT_BASE64 is only required when reading Firebase Remote Config; use github_environment when it is environment-scoped |
dependency-review.yml |
GITHUB_TOKEN |
None required; uses actions/dependency-review-action |
stale.yml |
GITHUB_TOKEN |
issues: write, pull-requests: write granted by reusable |
auto-assign-reviewers.yml |
GITHUB_TOKEN |
pull-requests: write granted by reusable |
All references use @main so repos pick up updates automatically. If you need stability, pin to a specific commit SHA.