Skip to content

c4a8/c4a8-code-reusable-actions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

c4a8-code-reusable-actions

Reusable GitHub workflows for repositories in the c4a8 org.

Table of contents

Deploy Azure Function workflow

This workflow simplifies the process of deploying Azure Functions. Use this reusable workflow at .github/workflows/deploy-azure-function.yml.

Calling the workflow

# .github/workflows/deploy-azure-function.yml in a consumer repository
name: Deploy Azure Function

on:
  push:
    branches:
      - main

jobs:
  publish:
    uses: c4a8/c4a8-code-reusable-actions/.github/workflows/deploy-azure-function.yml@main
    with:
      dotnet_version: "10.x" # required: version of .NET SDK to use
      tenant_id: "tenant-id" # required: of the tenant id
      subscription_id: "subscription-id" # required: of the subscription id
      client_id: "client-id" # required: of the client id of the specific function
      function_app_name: "function-app-name" # required: name of the function app
      environment: "production" # optional: deployment environment (e.g., 'staging', 'production')
      funcignore: false # optional: respect the .funcignore file during deployment
      nuget_source_name: "nuget-src" # optional: if you have configured a nuget.config
      project_path: "project/project.csproj" # required: relative path to the .csproj file to build and publish
    secrets:
      github_pat: "${{ secrets.GITHUB_TOKEN }}" # optional: required when nuget_source_name is set

Inputs

  • dotnet_version (string, default: empty) – Version of .NET SDK to use (e.g., '10.x').
  • tenant_id (string, default: empty) – Azure Tenant ID (GUID). Found in Azure Portal under Azure Active Directory > Overview.
  • subscription_id (string, default: empty) – Azure Subscription ID (GUID). Found in Azure Portal under Subscriptions.
  • client_id (string, default: empty) – Azure Client ID (GUID) of the app registration used for OIDC authentication.
  • function_app_name (string, default: empty) – Provide the function app name.
  • environment (string, default: production) – (Optional) Define your deployment environment (e.g., 'staging', 'production').
  • funcignore (boolean, default: false) – (Optional) Respect the .funcignore file during deployment. A warning shows up if set to true without .funcignore file.
  • nuget_source_name (string, default: "") – (Optional) Name of the NuGet package source (used in NuGetPackageSourceCredentials_{name}). Leave empty to skip NuGet authentication.
  • project_path (string, default: empty) – Relative path to the .csproj file to build and publish.

Secrets

  • github_pat (secret) – (Optional) GitHub Personal Access Token. Pass via secrets: github_pat: ${{ secrets.GITHUB_TOKEN }}. Required when nuget_source_name is set.

Publish NuGet package workflow

This workflow simplifies the process of publishing NuGet packages. Use this reusable workflow at .github/workflows/publish-nuget-package-github.yml. It is designed to be used for publishing packages in the package space of a GitHub organization.

Calling the workflow

# .github/workflows/publish-nuget-package-github.yml in a consumer repository
name: Publish NuGet package

on:
  push:
    branches:
      - main

jobs:
  publish:
    uses: c4a8/c4a8-code-reusable-actions/.github/workflows/publish-nuget-package-github.yml@main
    with:
      dotnet_version: "10.x" # required: version of .NET SDK to use
      project_path: "project/project.csproj" # required: path to the .NET project file
      package_output: "project/bin/Release" # required: output directory for the NuGet package
      package_version: "0.0.1" # required: version of the NuGet package to publish
      assembly_version: "0.0.1" # optional: set specific assembly version
    secrets:
      github_pat: your-pat-token # required: GitHub Personal Access Token with 'write:packages' scope - use GitHub's secret vars for this

Inputs

  • dotnet_version (string, default: empty) – Version of .NET SDK to use (e.g., '10.x').
  • project_path (string, default: empty) – Path to the .NET project file (e.g., 'project/project.csproj').
  • package_output (string, default: empty) – Output directory for the NuGet package (e.g., 'project/bin/Release').
  • package_version (string, default: empty) – Version of the NuGet package to publish (e.g., '1.0.0').
  • assembly_version (string, default: package version) – (Optional) Set specific assembly version (e.g., '1.0.0'). If not set, it will default to package version. This version usually has the same value as the package_version.
  • github_pat (string, default: empty) – GitHub Personal Access Token with 'write:packages' scope. Use it as secret variable -> ${{ secrets.GITHUB_TOKEN }}.

Epoch Semantic Versioning workflow

This workflow generates an epoch semantic version of the form vYYYY.WW.P (e.g. v2026.8.2), where YYYY is the ISO year, WW is the ISO calendar week, and P is the patch level.

The bump type is determined from commit messages (same rules as the Semantic Versioning workflow):

  • Release — triggered by feat:, feat(<scope>):, BREAKING CHANGE:, or any type ending in !: (e.g. fix!:).
    • If the current calendar week/year differs from the previous stable tag: advance to the current year and week, reset patch to 0.
    • If the current calendar week/year is the same as the previous stable tag: increment patch (behaves like a patch bump).
  • Patch — any other commit message: increment the patch level and keep the year and week of the previous stable tag, regardless of the current date. Use the reusable workflow at .github/workflows/epoch-semver-version.yml to compute the next epoch semantic version, expose it as an output, and tag the current commit.

Note: This workflow is very similar to the Semantic Versioning workflow. So please fall back to that documentation for further information.

Calling the workflow

# .github/workflows/epoch-semver-version.yml in a consumer repository
name: Release

on:
  push:
    branches:
      - main

jobs:
  version:
    uses: c4a8/c4a8-code-reusable-actions/.github/workflows/epoch-semver-version.yml@main
    with:
      prefix: license-module # optional: prefix for tags like license-module-vX.Y.Z
      suppress_release: false # optional: set true to skip creating a GitHub release
      suppress_tag: false # optional: set true to skip both tag and release creation
      check_last_commit_only: false # optional: set true to only inspect the latest commit
      is_prerelease: false # optional: set true to generate a prerelease version
      prerelease_name: prerelease # optional: name for prerelease identifier (e.g., 'rc', 'alpha', 'beta')

  publish:
    runs-on: ubuntu-latest
    needs: version
    steps:
      - name: Show generated version
        run: |
          echo "Version: ${{ needs.version.outputs.version }}"
          echo "Tag:     ${{ needs.version.outputs.tag }}"
          echo "Bump:    ${{ needs.version.outputs.bump_type }}"
          echo "Prev tag:${{ needs.version.outputs.previous_tag }}"
          echo "Commit:  ${{ needs.version.outputs.commit_subject }}"

Inputs

  • prefix (string, default: empty) – Optional prefix prepended to generated tags (for example license-module-vYYYY.WW.P).
  • suppress_release (boolean, default: false) – When true, skips creating a GitHub release while still creating tags (unless suppressed below).
  • suppress_tag (boolean, default: false) – When true, skips creating both the Git tag and the GitHub release.
  • check_last_commit_only (boolean, default: false) – When true, only the most recent commit is inspected to determine the bump type instead of all commits since the previous tag.
  • is_prerelease (boolean, default: false) – When true, generates a prerelease version (for example v2026.8.2-rc.1).
  • prerelease_name (string, default: "prerelease") – Name for the prerelease identifier (for example rc, alpha, beta).

Outputs

  • version – The calculated semantic version (for example 2026.8.2).
  • tag – The tag name that would be created (for example v2026.8.2 or module-v2026.8.2).
  • bump_type – The bump classification applied (release or patch).
  • previous_tag – The most recent matching tag prior to this run, if any.
  • commit_subject – The commit message subject that determined the bump decision.

Bump rules

The workflow inspects commit messages and applies the following precedence:

  • Release: If any commit matches feat:, feat(<scope>):, BREAKING CHANGE:, or any type ending in !: (for example feat!:, fix!:, chore!:, feat(scope)!:).
  • Patch: Any other commit message.

If no existing epoch-versioned tags are found, versioning starts from {currentYear}.{currentWeek}.0 (for a release bump) or {currentYear}.{currentWeek}.1 (for a patch bump).

Each run also publishes (or updates) a Git tag matching the new version. By default tags look like vYYYY.WW.P, but you can provide a prefix input (for example license-module) to emit tags such as license-module-vYYYY.WW.P. The workflow creates a GitHub release with auto-generated release notes for the generated tag. Existing tags or releases are detected and left untouched.

Semantic Versioning workflow

Use the reusable workflow at .github/workflows/semver-version.yml to compute the next semantic version, expose it as an output, and tag the current commit.

Calling the workflow

# .github/workflows/release.yml in a consumer repository
name: Release

on:
  push:
    branches:
      - main

jobs:
  version:
    uses: c4a8/c4a8-code-reusable-actions/.github/workflows/semver-version.yml@main
    with:
      prefix: license-module # optional: prefix for tags like license-module-vX.Y.Z
      suppress_release: false # optional: set true to skip creating a GitHub release
      suppress_tag: false # optional: set true to skip both tag and release creation
      check_last_commit_only: false # optional: set true to only inspect the latest commit
      is_prerelease: false # optional: set true to generate a prerelease version
      prerelease_name: prerelease # optional: name for prerelease identifier (e.g., 'rc', 'alpha', 'beta')

  publish:
    runs-on: ubuntu-latest
    needs: version
    steps:
      - name: Show generated version
        run: |
          echo "Version: ${{ needs.version.outputs.version }}"
          echo "Tag:     ${{ needs.version.outputs.tag }}"
          echo "Bump:    ${{ needs.version.outputs.bump_type }}"
          echo "Prev tag:${{ needs.version.outputs.previous_tag }}"
          echo "Commit:  ${{ needs.version.outputs.commit_subject }}"

Inputs

  • prefix (string, default: empty) – Optional prefix prepended to generated tags (for example license-module-vX.Y.Z).
  • suppress_release (boolean, default: false) – When true, skips creating a GitHub release while still creating tags (unless suppressed below).
  • suppress_tag (boolean, default: false) – When true, skips creating both the Git tag and the GitHub release.
  • check_last_commit_only (boolean, default: false) – When true, only the most recent commit is inspected to determine the bump type instead of all commits since the previous tag.
  • is_prerelease (boolean, default: false) – When true, generates a prerelease version (for example 1.2.3-rc.1).
  • prerelease_name (string, default: "prerelease") – Name for the prerelease identifier (for example rc, alpha, beta).

Outputs

  • version – The calculated semantic version (for example 1.2.3).
  • tag – The tag name that would be created (for example v1.2.3 or module-v1.2.3).
  • bump_type – The bump classification applied (major, minor, or patch).
  • previous_tag – The most recent matching tag prior to this run, if any.
  • commit_subject – The commit message subject that determined the bump decision.

Bump rules

The workflow inspects the latest commit message and applies the following precedence:

  • MAJOR: If the first word ends with !: (for example feat!:, fix!:, chore!:, feat(scope)!:).
  • MINOR: If the subject starts with feat: or feat(<scope>):, case-insensitive.
  • PATCH: Any other commit message.

If no existing tags matching v* are found, versioning starts from 0.0.0.

Each run also publishes (or updates) a Git tag matching the new version. By default tags look like vX.Y.Z, but you can provide a prefix input (for example license-module) to emit tags such as license-module-vX.Y.Z. The workflow creates a GitHub release with auto-generated release notes for the generated tag. Existing tags or releases are detected and left untouched.

Commit message hook

A PowerShell-based Git commit-msg hook is available at git/hooks/enforceConventionalCommits/commit-msg.ps1 to enforce the Conventional Commits standard locally before commits are created.

Installation

Windows

  1. Copy both the commit-msg.ps1 and commit-msg to your repository's .git/hooks directory

Mac / Linux

  1. Copy just the commit-msg.ps1 to your repository's .git/hooks directory
  2. Remove the .ps1 ending (so the final filename inside the .git/hooks directory is commit-msg)
  3. Add execution permissions:
chmod +x .git/hooks/commit-msg

What it validates

The hook validates that commit messages follow the Conventional Commits format:

<type>[optional scope][optional !]: <description>

[optional body]

[optional footer(s)]

Valid types

Type Description
feat A new feature
fix A bug fix
docs Documentation only changes
style Code style changes (formatting, missing semicolons, etc.)
refactor Code change that neither fixes a bug nor adds a feature
perf Performance improvements
test Adding or correcting tests
build Changes to build system or dependencies
ci Changes to CI configuration files and scripts
chore Other changes that don't modify src or test files
revert Reverts a previous commit
deps Dependency updates

Examples

feat: add user authentication
fix(api): resolve null reference exception
feat(auth)!: change login flow (breaking change)
docs: update README with setup instructions

Warnings

The hook will display warnings (but not reject the commit) for:

  • Long subject lines: Subject lines longer than 72 characters
  • Missing breaking change documentation: When ! is used but no BREAKING CHANGE: section is present in the body

About

Contains reusable actions that can be used from other repositories

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors