Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

44 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

github-actions-workflows

Org-wide reusable GitHub Actions workflows for minhdqdev-org.

Available Workflows

ci.yml — Docker CI

Builds and pushes a Docker image to Harbor, then sends a success notification to NotiHub. Branch is detected at runtime to apply the correct tag strategy:

Branch Tag produced Environment ArgoCD strategy
develop dev-<short_sha> DEV latest, regexp:^dev-.*$
rc/<version> <version>-rc.<commit_count> UAT semver, regexp:^.*-rc\.[0-9]+$
main / master <version> + latest PROD semver

Version is resolved from package.json, pyproject.toml, or Cargo.toml. Falls back to the short commit SHA if none are present.

Name RC branches after the version they release — rc/0.1.120, not rc/my-feature. The workflow triggers on rc/** so any name builds, but the branch name is how anyone reading the branch list knows which release is in UAT.

<commit_count> is git rev-list --count HEAD, not github.run_number: it is per-branch monotonic with no gaps from unrelated branches. This is why the checkout step sets fetch-depth: 0 — under the default shallow clone the count is always 1, every RC builds <version>-rc.1, and ArgoCD Image Updater sees no newer tag and silently stops deploying.

It also means the version must be bumped for each new RC of the same release. Two RC builds at the same version and commit count collide on the tag; the second overwrites the first and nothing deploys.

Usage

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [develop, main, "rc/**"]

jobs:
  ci:
    uses: minhdqdev-org/github-actions-workflows/.github/workflows/ci.yml@main

Inputs

Input Default Description
dockerfile ./Dockerfile Path to the Dockerfile
dockerfile_target "" Build target for multi-stage Dockerfiles

Custom Dockerfile path

jobs:
  ci:
    uses: minhdqdev-org/github-actions-workflows/.github/workflows/ci.yml@main
    with:
      dockerfile: ./deploy/dockerfile

Multi-stage build target

jobs:
  ci:
    uses: minhdqdev-org/github-actions-workflows/.github/workflows/ci.yml@main
    with:
      dockerfile_target: production

Test prerequisite before Docker build

jobs:
  test:
    if: github.ref == 'refs/heads/main'
    runs-on: [self-hosted, minhdqdev-org, manual]
    steps:
      - uses: actions/checkout@v4
      - run: bun install --frozen-lockfile
      - run: bun test --coverage

  ci:
    needs: [test]
    if: always() && (needs.test.result == 'success' || needs.test.result == 'skipped')
    uses: minhdqdev-org/github-actions-workflows/.github/workflows/ci.yml@main

pr-check.yml — pre-merge gate

Runs on a repo's pull_request trigger. Builds and pushes nothing, so it is safe on every PR. ci.yml runs after code lands on a branch; this runs before.

Job Tool Scope
Secret scan gitleaks commits the PR adds (base..head)
SAST Semgrep findings new relative to the PR base commit
Dependency scan Trivy fs whole lockfile (uv.lock, bun.lock, package-lock.json, pubspec.lock, ...)
Dockerfile lint hadolint skipped when there is no Dockerfile
Checks caller-supplied install_command, then check_command and test_command
PR check — one job to point a required status check at

Findings are scoped to the change where possible, so a brownfield repo does not start red. The dependency scan cannot be scoped to the diff, because an advisory belongs to the dependency. Set dependency_scan_fail: false to report without blocking while a backlog is cleared, then flip it back.

# .github/workflows/pr-check.yml
name: PR Check

on:
  pull_request:
    branches: [develop, main]

jobs:
  pr-check:
    uses: minhdqdev-org/github-actions-workflows/.github/workflows/pr-check.yml@main
    with:
      install_command: uv sync --frozen --extra dev
      check_command: uv run ruff check src/
Input Default Description
secret_scan / sast / dependency_scan / dockerfile_lint true Enable each job
sast_fail / dependency_scan_fail / checks_fail true false makes that job report-only
dependency_severities CRITICAL,HIGH Severities that count as findings
semgrep_config p/default Semgrep ruleset
dockerfile ./Dockerfile Dockerfile to lint
working_directory . Where the install, check and test commands run
install_command "" Empty skips the Checks job
check_command / test_command "" Empty skips that step
runs_on ["self-hosted","minhdqdev-org","manual"] JSON array of runner labels

test_command must not need services the runner does not have (for example a database).

Nothing from the github or inputs contexts may appear inside a run: body in this repo. ${{ }} is substituted as raw text before bash parses the script, so a branch name becomes code. Pass the value through env: instead.

Requirements

  • Runner: [self-hosted, minhdqdev-org, manual] with Harbor credentials injected via envFrom (HARBOR_USERNAME, HARBOR_PASSWORD) on the runner pod.
  • Registry: harbor.internal.minhdq.dev/minhdqdev/<repo-name>
  • Build cache: stored at harbor.internal.minhdq.dev/minhdqdev/<repo-name>:buildcache

Further reading

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors