Reusable GitHub Workflows
A collection of reusable GitHub Actions workflows.
Table of Contents
Workflows
Go Release (go-release.yml)
A complete CI/CD workflow for Go projects that handles testing, cross-platform builds, releases, and Homebrew tap updates.
Features
- Runs tests with configurable test command
- Cross-platform builds (Linux, macOS, Windows)
- Automated releases via release-please
- Automatic Homebrew tap updates via repository dispatch
Usage
name: Release
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
release:
uses: chenasraf/workflows/.github/workflows/go-release.yml@master
with:
name: my-cli
go-version: '1.24'
platforms: '["linux/amd64", "darwin/arm64"]'
main-branch: main
homebrew-tap-repo: myorg/homebrew-tap
secrets:
REPO_DISPATCH_PAT: ${{ secrets.REPO_DISPATCH_PAT }}
Inputs
| Input | Description | Required | Default |
|---|---|---|---|
name | Binary/project name | Yes | - |
go-version | Go version to use | No | 1.24 |
platforms | JSON array of platforms to build | No | ["linux/amd64", "darwin/amd64", "darwin/arm64", "windows/amd64"] |
package | Go package path (empty for root) | No | "" |
compress | Compress build artifacts | No | true |
test-command | Test command to run | No | go test -v ./... |
skip-tests | Skip running tests | No | false |
main-branch | Main branch name for releases | No | master |
homebrew-tap-repo | Homebrew tap repo for dispatch (leave empty to skip) | No | “ |
Secrets
| Secret | Description | Required |
|---|---|---|
REPO_DISPATCH_PAT | PAT for dispatching to homebrew tap repo | No |
Manual Homebrew Release (manual-homebrew-release.yml)
Manually triggers a Homebrew tap update for the latest release. Useful when you need to re-trigger a Homebrew formula update without creating a new release.
Features
- Fetches the latest release tag and body from the repository
- Sends a repository dispatch event to your Homebrew tap repo
- Works with any Homebrew tap that listens for
trigger-from-releaseevents with payload:{ tag, repo, body }
Usage
name: Manual Homebrew Release
on:
workflow_dispatch:
jobs:
homebrew:
uses: chenasraf/workflows/.github/workflows/manual-homebrew-release.yml@master
with:
homebrew-tap-repo: myorg/homebrew-tap
secrets:
REPO_DISPATCH_PAT: ${{ secrets.REPO_DISPATCH_PAT }}
Inputs
| Input | Description | Required | Default |
|---|---|---|---|
homebrew-tap-repo | Homebrew tap repo to dispatch to (e.g., owner/homebrew-tap) | Yes | - |
Secrets
| Secret | Description | Required |
|---|---|---|
REPO_DISPATCH_PAT | PAT for dispatching to homebrew tap repo | Yes |
Release Please + Fastlane Changelog (release-please-fastlane-changelog.yml)
Runs release-please, then when a release PR is
created or updated, extracts the changelog for the current version from CHANGELOG.md, formats it
for the Play Store (stripped of markdown links, commit hashes, etc.), truncates to the 500-char
limit, and writes it to one or more fastlane metadata directories. The changelog is amended into
release-please’s commit so the tagged release includes the file.
Features
- Runs release-please with configurable release type
- Extracts version-specific notes from
CHANGELOG.md - Strips commit links, reformats bullets, removes markdown headers
- Truncates to Play Store’s 500-char limit with a configurable trailer
- Writes to multiple output directories (e.g. Android + iOS fastlane metadata)
- Amends the release-please commit (no extra commits in the PR)
- Forwards
release_created,tag_name, andversionoutputs
Usage
name: CI/CD
on:
push:
branches: [master]
jobs:
release-please:
uses: chenasraf/workflows/.github/workflows/release-please-fastlane-changelog.yml@master
with:
release-type: dart
With multiple output directories (Android + iOS):
jobs:
release-please:
uses: chenasraf/workflows/.github/workflows/release-please-fastlane-changelog.yml@master
with:
release-type: dart
fastlane-changelog-dirs: |
fastlane/metadata/android/en-US/changelogs
fastlane/metadata/ios/en-US/changelogs
build:
needs: release-please
if: ${{ needs.release-please.outputs.release_created }}
# ...
Inputs
| Input | Description | Required | Default |
|---|---|---|---|
release-type | Release Please release type (dart, node, python, go, etc.) | Yes | - |
version-file | File containing the version string | No | pubspec.yaml |
changelog-file | Path to the CHANGELOG.md file | No | CHANGELOG.md |
fastlane-changelog-dirs | Newline-separated list of output directories | No | fastlane/metadata/android/en-US/changelogs |
max-length | Maximum changelog length in characters | No | 500 |
truncation-trailer | Text appended when the changelog is truncated | No | \n\n… see full notes on GitHub. |
Secrets
| Secret | Description | Required |
|---|---|---|
token | GitHub token for release-please (defaults to GITHUB_TOKEN) | No |
Outputs
| Output | Description |
|---|---|
release_created | Whether a release was created |
tag_name | The release tag name |
version | The release version |
Nextcloud Workflows
Reusable workflows for Nextcloud app development. These workflows include automatic path filtering to skip unnecessary runs when irrelevant files change.
PHPUnit MySQL (nextcloud-phpunit-mysql.yml)
Runs PHPUnit tests with MySQL database.
jobs:
phpunit:
uses: chenasraf/workflows/.github/workflows/nextcloud-phpunit-mysql.yml@nextcloud-latest
with:
php-versions-min: '8.1'
php-versions-max: '8.4'
mysql-version: '8.0'
path-filters: |
- 'lib/**'
- 'tests/**'
- 'composer.json'
| Input | Description | Required | Default |
|---|---|---|---|
php-versions-min | Minimum PHP version | No | 8.2 |
php-versions-max | Maximum PHP version | No | 8.3 |
mysql-version | MySQL version | No | 8.4 |
php-extensions | PHP extensions to install | No | (common extensions) |
path-filters | Paths to trigger on (YAML list) | No | (lib, tests, etc.) |
PHPUnit PostgreSQL (nextcloud-phpunit-pgsql.yml)
Runs PHPUnit tests with PostgreSQL database.
jobs:
phpunit:
uses: chenasraf/workflows/.github/workflows/nextcloud-phpunit-pgsql.yml@nextcloud-latest
with:
php-version: '8.2'
path-filters: |
- 'lib/**'
- 'tests/**'
| Input | Description | Required | Default |
|---|---|---|---|
php-version | PHP version | No | 8.3 |
php-extensions | PHP extensions to install | No | (common extensions) |
path-filters | Paths to trigger on (YAML list) | No | (lib, tests, etc.) |
PHPUnit Incremental Migration (nextcloud-phpunit-incremental.yml)
Tests database migrations by upgrading from a baseline version.
jobs:
incremental:
uses: chenasraf/workflows/.github/workflows/nextcloud-phpunit-incremental.yml@nextcloud-latest
with:
baseline-version: v1.0.0
php-version: '8.2'
validation-query: 'SELECT COUNT(*) FROM oc_myapp_users'
path-filters: |
- 'lib/Migration/**'
- 'appinfo/info.xml'
| Input | Description | Required | Default |
|---|---|---|---|
baseline-version | Git tag/ref to upgrade from | Yes | - |
php-version | PHP version | No | 8.3 |
php-extensions-mysql | PHP extensions for MySQL tests | No | (common extensions) |
php-extensions-pgsql | PHP extensions for PostgreSQL tests | No | (common extensions) |
validation-query | SQL query to validate migration | No | (empty) |
path-filters | Paths to trigger on (YAML list) | No | (lib, tests, etc.) |
Psalm Static Analysis (nextcloud-psalm.yml)
Runs Psalm static analysis across supported Nextcloud versions.
jobs:
psalm:
uses: chenasraf/workflows/.github/workflows/nextcloud-psalm.yml@nextcloud-latest
with:
psalm-command: 'composer run psalm -- --show-info=true'
path-filters: |
- 'lib/**/*.php'
- 'psalm.xml'
| Input | Description | Required | Default |
|---|---|---|---|
psalm-command | Command to run Psalm | No | composer run psalm |
php-extensions | PHP extensions to install | No | (common extensions) |
path-filters | Paths to trigger on (YAML list) | No | **.php, psalm.xml |
PHP Lint (nextcloud-lint-php.yml)
Runs PHP syntax linting across supported PHP versions.
jobs:
lint:
uses: chenasraf/workflows/.github/workflows/nextcloud-lint-php.yml@nextcloud-latest
with:
lint-command: 'composer run lint -- --colors'
path-filters: |
- 'lib/**/*.php'
- 'appinfo/**/*.php'
| Input | Description | Required | Default |
|---|---|---|---|
lint-command | Command to run lint | No | composer run lint |
php-extensions | PHP extensions to install | No | (common extensions) |
path-filters | Paths to trigger on (YAML list) | No | **.php |
PHP-CS-Fixer (nextcloud-lint-php-cs.yml)
Checks PHP code style with PHP-CS-Fixer.
jobs:
cs:
uses: chenasraf/workflows/.github/workflows/nextcloud-lint-php-cs.yml@nextcloud-latest
with:
cs-check-command: 'vendor/bin/php-cs-fixer fix --dry-run --diff'
path-filters: |
- 'lib/**/*.php'
- 'tests/**/*.php'
| Input | Description | Required | Default |
|---|---|---|---|
cs-check-command | Command to check code style | No | composer run cs:check |
php-extensions | PHP extensions to install | No | (common extensions) |
path-filters | Paths to trigger on (YAML list) | No | **.php, .php-cs-fixer.dist.php |
ESLint (nextcloud-lint-eslint.yml)
Runs ESLint on frontend code.
jobs:
eslint:
uses: chenasraf/workflows/.github/workflows/nextcloud-lint-eslint.yml@nextcloud-latest
with:
lint-command: 'pnpm lint --max-warnings 0'
path-filters: |
- 'src/**/*.ts'
- 'src/**/*.vue'
| Input | Description | Required | Default |
|---|---|---|---|
lint-command | Command to run lint | No | pnpm lint |
path-filters | Paths to trigger on (YAML list) | No | src/**, *.ts, *.js, etc. |
OpenAPI Lint (nextcloud-lint-openapi.yml)
Validates OpenAPI spec is up to date.
jobs:
openapi:
uses: chenasraf/workflows/.github/workflows/nextcloud-lint-openapi.yml@nextcloud-latest
with:
openapi-command: 'composer run generate-openapi'
typescript-types-pattern: 'src/api/types/*.ts'
path-filters: |
- 'lib/Controller/**/*.php'
- 'openapi.json'
| Input | Description | Required | Default |
|---|---|---|---|
openapi-command | Command to regenerate OpenAPI | No | composer run openapi |
typescript-types-pattern | Glob for TypeScript types | No | src/types/openapi/openapi*.ts |
path-filters | Paths to trigger on (YAML list) | No | lib/**/*.php, openapi.json |
AppInfo XML Lint (nextcloud-lint-appinfo-xml.yml)
Validates appinfo/info.xml against schema.
jobs:
xml:
uses: chenasraf/workflows/.github/workflows/nextcloud-lint-appinfo-xml.yml@nextcloud-latest
with:
xml-file: './custom/path/info.xml'
path-filters: |
- 'custom/path/info.xml'
| Input | Description | Required | Default |
|---|---|---|---|
xml-file | Path to the info.xml file | No | ./appinfo/info.xml |
schema-url | URL to XML schema | No | (Nextcloud schema) |
path-filters | Paths to trigger on (YAML list) | No | appinfo/info.xml |
NPM Build (nextcloud-build-npm.yml)
Builds frontend assets with pnpm.
jobs:
build:
uses: chenasraf/workflows/.github/workflows/nextcloud-build-npm.yml@nextcloud-latest
with:
build-command: 'pnpm build:prod'
path-filters: |
- 'src/**'
- 'package.json'
- 'pnpm-lock.yaml'
| Input | Description | Required | Default |
|---|---|---|---|
build-command | Command to run build | No | pnpm build |
path-filters | Paths to trigger on (YAML list) | No | src/**, *.json, etc. |
Vitest (nextcloud-vitest.yml)
Runs Vitest frontend tests.
jobs:
vitest:
uses: chenasraf/workflows/.github/workflows/nextcloud-vitest.yml@nextcloud-latest
with:
node-version: '20'
test-command: 'pnpm vitest run --coverage'
path-filters: |
- 'src/**'
- 'tests/**'
| Input | Description | Required | Default |
|---|---|---|---|
node-version | Node.js version to use | No | 22 |
test-command | Command to run tests | No | pnpm test:run |
path-filters | Paths to trigger on (YAML list) | No | src/**, *.ts, etc. |
Block Unconventional Commits (nextcloud-block-unconventional-commits.yml)
Blocks commits that don’t follow conventional commit format.
jobs:
commits:
uses: chenasraf/workflows/.github/workflows/nextcloud-block-unconventional-commits.yml@nextcloud-latest
with:
allowed-types: 'feat,fix,docs,chore,refactor'
| Input | Description | Required | Default |
|---|---|---|---|
allowed-types | Comma-separated list of allowed commit types | No | (feat, fix, docs, etc.) |
License
MIT