quality / commitlint (push) Skipped
quality / changes (push) Successful in 9s
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 34s
quality / web (push) Successful in 1m1s
quality / api (push) Successful in 49s
CD / quality (push) Successful in 2m40s
CD / publish (push) Successful in 3m40s
- Modified the CI workflow in `quality.yaml` to use `pnpm exec turbo` for running tests and builds, improving efficiency for the @evofw/api package. - Added a new export for development in `package.json` of the db package, allowing direct access to the source TypeScript file. These changes enhance the CI process and improve the development experience for the db package.
337 lines
11 KiB
YAML
337 lines
11 KiB
YAML
# Quality gates (reusable). Callers: ci.yaml (PR), cd.yaml (push main).
|
|
name: quality
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
is_pull_request:
|
|
type: boolean
|
|
required: true
|
|
base_sha:
|
|
type: string
|
|
required: false
|
|
default: ""
|
|
head_sha:
|
|
type: string
|
|
required: false
|
|
default: ""
|
|
before_sha:
|
|
type: string
|
|
required: false
|
|
default: ""
|
|
allow_registry_login:
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
secrets:
|
|
ACTIONS_PAT:
|
|
required: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
changes:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
openapi: ${{ steps.detect.outputs.openapi }}
|
|
web: ${{ steps.detect.outputs.web }}
|
|
api: ${{ steps.detect.outputs.api }}
|
|
docker: ${{ steps.detect.outputs.docker }}
|
|
steps:
|
|
- if: ${{ inputs.is_pull_request }}
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
- if: ${{ inputs.is_pull_request == false }}
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 2
|
|
- id: detect
|
|
name: Detect changed paths per module
|
|
env:
|
|
IS_PR: ${{ inputs.is_pull_request }}
|
|
BASE_SHA: ${{ inputs.base_sha }}
|
|
HEAD_SHA: ${{ inputs.head_sha }}
|
|
BEFORE_SHA: ${{ inputs.before_sha }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
openapi=false
|
|
web=false
|
|
api=false
|
|
docker=false
|
|
|
|
set_all_flags_true() {
|
|
openapi=true
|
|
web=true
|
|
api=true
|
|
docker=true
|
|
}
|
|
|
|
write_outputs() {
|
|
for v in openapi web api docker; do
|
|
eval "echo \"\$v=\$$v\"" >> "$GITHUB_OUTPUT"
|
|
done
|
|
}
|
|
|
|
if [ "$IS_PR" = "true" ]; then
|
|
FILES="$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")"
|
|
else
|
|
after="${HEAD_SHA:-$(git rev-parse HEAD)}"
|
|
before="$BEFORE_SHA"
|
|
if [ -n "$before" ] && [ "$before" != "0000000000000000000000000000000000000000" ]; then
|
|
FILES="$(git diff --name-only "$before" "$after")"
|
|
elif git rev-parse --verify HEAD~1 >/dev/null 2>&1; then
|
|
FILES="$(git diff --name-only HEAD~1 HEAD)"
|
|
else
|
|
set_all_flags_true
|
|
write_outputs
|
|
echo "No parent commit — full pipeline (all modules)"
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$(printf '%s' "$FILES" | tr -d '[:space:]')" ]; then
|
|
set_all_flags_true
|
|
write_outputs
|
|
echo "Empty diff — full pipeline fallback"
|
|
exit 0
|
|
fi
|
|
|
|
full_pipeline=false
|
|
|
|
while IFS= read -r f || [ -n "${f:-}" ]; do
|
|
[ -z "${f:-}" ] && continue
|
|
case "$f" in
|
|
.gitea/workflows/*|scripts/*)
|
|
full_pipeline=true
|
|
;;
|
|
docs/openapi.yaml|redocly.yaml)
|
|
openapi=true
|
|
;;
|
|
.cursor/*|.claude/*|.codegraph/*|.agents/*)
|
|
;;
|
|
*.md|AGENTS.md)
|
|
;;
|
|
apps/web/README.md|apps/web/components.json|packages/ui/components.json)
|
|
;;
|
|
apps/web/*|packages/ui/*)
|
|
web=true
|
|
;;
|
|
apps/api/*|packages/db/*)
|
|
api=true
|
|
;;
|
|
packages/shared/*)
|
|
web=true
|
|
api=true
|
|
;;
|
|
deploy/compose/*|deploy/docker/*|.dockerignore)
|
|
docker=true
|
|
;;
|
|
docs/*)
|
|
;;
|
|
package.json|pnpm-lock.yaml|pnpm-workspace.yaml|turbo.json|.releaserc.json|commitlint.config.cjs)
|
|
full_pipeline=true
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done <<< "$FILES"
|
|
|
|
if $full_pipeline; then
|
|
set_all_flags_true
|
|
fi
|
|
|
|
write_outputs
|
|
|
|
echo "Changed files (first 30):"
|
|
printf '%s\n' "$FILES" | head -n 30
|
|
echo "--- flags ---"
|
|
echo "openapi=$openapi web=$web api=$api docker=$docker full_pipeline=$full_pipeline"
|
|
|
|
openapi:
|
|
needs: [changes]
|
|
if: needs.changes.outputs.openapi == 'true' || needs.changes.outputs.web == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
with:
|
|
node-version: "22"
|
|
- name: Export cache paths
|
|
run: sh scripts/ci/export-cache-env.sh
|
|
- id: pnpm-hash
|
|
run: echo "key=$(sha256sum pnpm-lock.yaml | awk '{print $1}')" >> "$GITHUB_OUTPUT"
|
|
- id: pnpm-cache
|
|
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
|
with:
|
|
path: |
|
|
${{ env.PNPM_STORE_DIR }}
|
|
${{ env.COREPACK_HOME }}
|
|
node_modules
|
|
apps/web/node_modules
|
|
apps/api/node_modules
|
|
packages/ui/node_modules
|
|
packages/shared/node_modules
|
|
packages/db/node_modules
|
|
key: pnpm-${{ runner.os }}-${{ steps.pnpm-hash.outputs.key }}
|
|
restore-keys: |
|
|
pnpm-${{ runner.os }}-
|
|
- name: pnpm install, Redocly
|
|
env:
|
|
PNPM_CACHE_HIT: ${{ steps.pnpm-cache.outputs.cache-hit }}
|
|
run: |
|
|
set -euxo pipefail
|
|
sh scripts/ci/pnpm-ci.sh
|
|
pnpm exec redocly lint docs/openapi.yaml
|
|
|
|
web:
|
|
needs: [changes]
|
|
if: needs.changes.outputs.web == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
with:
|
|
node-version: "22"
|
|
- name: Export cache paths
|
|
run: sh scripts/ci/export-cache-env.sh
|
|
- id: pnpm-hash
|
|
run: echo "key=$(sha256sum pnpm-lock.yaml | awk '{print $1}')" >> "$GITHUB_OUTPUT"
|
|
- id: pnpm-cache
|
|
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
|
with:
|
|
path: |
|
|
${{ env.PNPM_STORE_DIR }}
|
|
${{ env.COREPACK_HOME }}
|
|
node_modules
|
|
apps/web/node_modules
|
|
apps/api/node_modules
|
|
packages/ui/node_modules
|
|
packages/shared/node_modules
|
|
packages/db/node_modules
|
|
key: pnpm-${{ runner.os }}-${{ steps.pnpm-hash.outputs.key }}
|
|
restore-keys: |
|
|
pnpm-${{ runner.os }}-
|
|
- name: pnpm install, typecheck, build
|
|
env:
|
|
PNPM_CACHE_HIT: ${{ steps.pnpm-cache.outputs.cache-hit }}
|
|
run: |
|
|
set -euxo pipefail
|
|
sh scripts/ci/pnpm-ci.sh
|
|
pnpm --filter @evofw/web run typecheck
|
|
pnpm --filter @evofw/web run build
|
|
|
|
api:
|
|
needs: [changes]
|
|
if: needs.changes.outputs.api == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
with:
|
|
node-version: "22"
|
|
- name: Export cache paths
|
|
run: sh scripts/ci/export-cache-env.sh
|
|
- id: pnpm-hash
|
|
run: echo "key=$(sha256sum pnpm-lock.yaml | awk '{print $1}')" >> "$GITHUB_OUTPUT"
|
|
- id: pnpm-cache
|
|
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
|
with:
|
|
path: |
|
|
${{ env.PNPM_STORE_DIR }}
|
|
${{ env.COREPACK_HOME }}
|
|
node_modules
|
|
apps/web/node_modules
|
|
apps/api/node_modules
|
|
packages/ui/node_modules
|
|
packages/shared/node_modules
|
|
packages/db/node_modules
|
|
key: pnpm-${{ runner.os }}-${{ steps.pnpm-hash.outputs.key }}
|
|
restore-keys: |
|
|
pnpm-${{ runner.os }}-
|
|
- name: pnpm install, test, build
|
|
env:
|
|
PNPM_CACHE_HIT: ${{ steps.pnpm-cache.outputs.cache-hit }}
|
|
run: |
|
|
set -euxo pipefail
|
|
sh scripts/ci/pnpm-ci.sh
|
|
pnpm exec turbo run test --filter=@evofw/api
|
|
pnpm exec turbo run build --filter=@evofw/api
|
|
|
|
commitlint:
|
|
if: inputs.is_pull_request
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
with:
|
|
node-version: "22"
|
|
- name: Export cache paths
|
|
run: sh scripts/ci/export-cache-env.sh
|
|
- id: pnpm-hash
|
|
run: echo "key=$(sha256sum pnpm-lock.yaml | awk '{print $1}')" >> "$GITHUB_OUTPUT"
|
|
- id: pnpm-cache
|
|
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
|
with:
|
|
path: |
|
|
${{ env.PNPM_STORE_DIR }}
|
|
${{ env.COREPACK_HOME }}
|
|
node_modules
|
|
apps/web/node_modules
|
|
apps/api/node_modules
|
|
packages/ui/node_modules
|
|
packages/shared/node_modules
|
|
packages/db/node_modules
|
|
key: pnpm-${{ runner.os }}-${{ steps.pnpm-hash.outputs.key }}
|
|
restore-keys: |
|
|
pnpm-${{ runner.os }}-
|
|
- name: Lint commit messages
|
|
env:
|
|
BASE_SHA: ${{ inputs.base_sha }}
|
|
HEAD_SHA: ${{ inputs.head_sha }}
|
|
PNPM_CACHE_HIT: ${{ steps.pnpm-cache.outputs.cache-hit }}
|
|
run: |
|
|
set -euxo pipefail
|
|
sh scripts/ci/pnpm-ci.sh
|
|
pnpm exec commitlint --from "$BASE_SHA" --to "$HEAD_SHA"
|
|
|
|
docker-check:
|
|
needs: [changes]
|
|
if: inputs.is_pull_request && needs.changes.outputs.docker == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
|
with:
|
|
name: evofw
|
|
driver: docker-container
|
|
cleanup: false
|
|
- name: Log in to Gitea Registry
|
|
if: inputs.allow_registry_login
|
|
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
|
with:
|
|
registry: git.shx.one
|
|
username: ${{ gitea.actor }}
|
|
password: ${{ secrets.ACTIONS_PAT }}
|
|
- name: bake --print
|
|
working-directory: deploy/docker
|
|
env:
|
|
BUILDX_BAKE_ENTITLEMENTS_FS: "0"
|
|
BUILDX_BAKE_FILE_RELATIVE_PATHS: "1"
|
|
run: docker buildx bake --allow=fs.read="${{ github.workspace }}" -f docker-bake.hcl --print default
|
|
- name: bake (no push)
|
|
if: inputs.allow_registry_login
|
|
working-directory: deploy/docker
|
|
env:
|
|
BUILDX_BAKE_ENTITLEMENTS_FS: "0"
|
|
BUILDX_BAKE_FILE_RELATIVE_PATHS: "1"
|
|
run: |
|
|
set -euxo pipefail
|
|
owner_lc="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
|
|
export CACHE_REF_NODE="git.shx.one/${owner_lc}/evofw-buildcache:node-buildcache"
|
|
docker buildx bake --allow=fs.read="${{ github.workspace }}" -f docker-bake.hcl default
|