Skip to content

dev v2.0.3

dev v2.0.3 #130

Workflow file for this run

name: CI
on:
pull_request:
branches: ['*']
workflow_dispatch:
jobs:
backend-lint:
name: Backend Lint
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
outputs:
pylint: ${{ steps.pylint.outputs.passed }}
ruff: ${{ steps.ruff.outputs.passed }}
mypy: ${{ steps.mypy.outputs.passed }}
pylint_output: ${{ steps.pylint.outputs.summary }}
ruff_output: ${{ steps.ruff.outputs.summary }}
mypy_output: ${{ steps.mypy.outputs.summary }}
defaults:
run:
working-directory: backend
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.14'
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Cache uv dependencies
uses: actions/cache@v5
with:
path: ~/.cache/uv
key: ${{ runner.os }}-uv-${{ hashFiles('backend/uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-
- name: Install dependencies
run: uv sync --locked --all-extras
- name: Run pylint
id: pylint
run: |
if uv run pylint . > pylint-output.txt 2>&1; then
echo "passed=true" >> $GITHUB_OUTPUT
echo "summary=No issues" >> $GITHUB_OUTPUT
else
echo "passed=false" >> $GITHUB_OUTPUT
count=$(grep -c ":" pylint-output.txt || echo "?")
echo "summary=$count issues" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Upload pylint output
if: always()
uses: actions/upload-artifact@v6
with:
name: pylint-output
path: backend/pylint-output.txt
retention-days: 1
- name: Run ruff
id: ruff
run: |
if uv run ruff check . > ruff-output.txt 2>&1; then
echo "passed=true" >> $GITHUB_OUTPUT
echo "summary=No issues" >> $GITHUB_OUTPUT
else
echo "passed=false" >> $GITHUB_OUTPUT
count=$(grep -c ":" ruff-output.txt || echo "?")
echo "summary=$count issues" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Upload ruff output
if: always()
uses: actions/upload-artifact@v6
with:
name: ruff-output
path: backend/ruff-output.txt
retention-days: 1
- name: Run mypy
id: mypy
run: |
if uv run mypy . > mypy-output.txt 2>&1; then
echo "passed=true" >> $GITHUB_OUTPUT
echo "summary=No issues" >> $GITHUB_OUTPUT
else
echo "passed=false" >> $GITHUB_OUTPUT
count=$(grep -c "error:" mypy-output.txt || echo "?")
echo "summary=$count errors" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Upload mypy output
if: always()
uses: actions/upload-artifact@v6
with:
name: mypy-output
path: backend/mypy-output.txt
retention-days: 1
frontend-eslint:
name: ESLint (${{ matrix.app }})
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
strategy:
fail-fast: false
matrix:
app: [admin-app, user-app]
outputs:
admin_passed: ${{ steps.result.outputs.admin_passed }}
user_passed: ${{ steps.result.outputs.user_passed }}
admin_summary: ${{ steps.result.outputs.admin_summary }}
user_summary: ${{ steps.result.outputs.user_summary }}
defaults:
run:
working-directory: frontend/${{ matrix.app }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Get pnpm store directory
id: pnpm-cache
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v5
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('frontend/${{ matrix.app }}/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run ESLint
id: eslint
run: |
if pnpm run lint:eslint > eslint-output.txt 2>&1; then
echo "passed=true" >> $GITHUB_OUTPUT
echo "summary=No issues" >> $GITHUB_OUTPUT
else
echo "passed=false" >> $GITHUB_OUTPUT
count=$(grep -c "^/" eslint-output.txt || echo "?")
echo "summary=$count files with issues" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Set matrix output
id: result
run: |
if [ "${{ matrix.app }}" == "admin-app" ]; then
echo "admin_passed=${{ steps.eslint.outputs.passed }}" >> $GITHUB_OUTPUT
echo "admin_summary=${{ steps.eslint.outputs.summary }}" >> $GITHUB_OUTPUT
else
echo "user_passed=${{ steps.eslint.outputs.passed }}" >> $GITHUB_OUTPUT
echo "user_summary=${{ steps.eslint.outputs.summary }}" >> $GITHUB_OUTPUT
fi
- name: Upload eslint output
if: always()
uses: actions/upload-artifact@v6
with:
name: eslint-${{ matrix.app }}-output
path: frontend/${{ matrix.app }}/eslint-output.txt
retention-days: 1
frontend-typescript:
name: TypeScript (${{ matrix.app }})
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
strategy:
fail-fast: false
matrix:
app: [admin-app, user-app]
outputs:
admin_passed: ${{ steps.result.outputs.admin_passed }}
user_passed: ${{ steps.result.outputs.user_passed }}
admin_summary: ${{ steps.result.outputs.admin_summary }}
user_summary: ${{ steps.result.outputs.user_summary }}
defaults:
run:
working-directory: frontend/${{ matrix.app }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Get pnpm store directory
id: pnpm-cache
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v5
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('frontend/${{ matrix.app }}/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run TypeScript
id: typescript
run: |
if pnpm run lint:types > typescript-output.txt 2>&1; then
echo "passed=true" >> $GITHUB_OUTPUT
echo "summary=No issues" >> $GITHUB_OUTPUT
else
echo "passed=false" >> $GITHUB_OUTPUT
count=$(grep -c "error TS" typescript-output.txt || echo "?")
echo "summary=$count errors" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Set matrix output
id: result
run: |
if [ "${{ matrix.app }}" == "admin-app" ]; then
echo "admin_passed=${{ steps.typescript.outputs.passed }}" >> $GITHUB_OUTPUT
echo "admin_summary=${{ steps.typescript.outputs.summary }}" >> $GITHUB_OUTPUT
else
echo "user_passed=${{ steps.typescript.outputs.passed }}" >> $GITHUB_OUTPUT
echo "user_summary=${{ steps.typescript.outputs.summary }}" >> $GITHUB_OUTPUT
fi
- name: Upload typescript output
if: always()
uses: actions/upload-artifact@v6
with:
name: typescript-${{ matrix.app }}-output
path: frontend/${{ matrix.app }}/typescript-output.txt
retention-days: 1
frontend-scss:
name: SCSS (${{ matrix.app }})
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
strategy:
fail-fast: false
matrix:
app: [admin-app, user-app]
outputs:
admin_passed: ${{ steps.result.outputs.admin_passed }}
user_passed: ${{ steps.result.outputs.user_passed }}
admin_summary: ${{ steps.result.outputs.admin_summary }}
user_summary: ${{ steps.result.outputs.user_summary }}
defaults:
run:
working-directory: frontend/${{ matrix.app }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Get pnpm store directory
id: pnpm-cache
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v5
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('frontend/${{ matrix.app }}/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run SCSS Lint
id: scss
run: |
if pnpm run lint:scss > scss-output.txt 2>&1; then
echo "passed=true" >> $GITHUB_OUTPUT
echo "summary=No issues" >> $GITHUB_OUTPUT
else
echo "passed=false" >> $GITHUB_OUTPUT
count=$(grep -c "✖" scss-output.txt || echo "?")
echo "summary=$count issues" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Set matrix output
id: result
run: |
if [ "${{ matrix.app }}" == "admin-app" ]; then
echo "admin_passed=${{ steps.scss.outputs.passed }}" >> $GITHUB_OUTPUT
echo "admin_summary=${{ steps.scss.outputs.summary }}" >> $GITHUB_OUTPUT
else
echo "user_passed=${{ steps.scss.outputs.passed }}" >> $GITHUB_OUTPUT
echo "user_summary=${{ steps.scss.outputs.summary }}" >> $GITHUB_OUTPUT
fi
- name: Upload scss output
if: always()
uses: actions/upload-artifact@v6
with:
name: scss-${{ matrix.app }}-output
path: frontend/${{ matrix.app }}/scss-output.txt
retention-days: 1
summary:
name: CI Summary
runs-on: ubuntu-latest
if: always() && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]'
needs: [backend-lint, frontend-eslint, frontend-typescript, frontend-scss]
permissions:
pull-requests: write
contents: read
steps:
- name: Download all artifacts
uses: actions/download-artifact@v7
with:
path: artifacts
- name: Generate Summary Comment
id: summary
run: |
check_icon() {
if [ "$1" == "true" ]; then
echo "[x]"
else
echo "[ ]"
fi
}
status_text() {
if [ "$1" == "true" ]; then
echo "Passed"
else
echo "Failed"
fi
}
PYLINT="${{ needs.backend-lint.outputs.pylint }}"
RUFF="${{ needs.backend-lint.outputs.ruff }}"
MYPY="${{ needs.backend-lint.outputs.mypy }}"
ESLINT_ADMIN="${{ needs.frontend-eslint.outputs.admin_passed }}"
ESLINT_USER="${{ needs.frontend-eslint.outputs.user_passed }}"
TS_ADMIN="${{ needs.frontend-typescript.outputs.admin_passed }}"
TS_USER="${{ needs.frontend-typescript.outputs.user_passed }}"
SCSS_ADMIN="${{ needs.frontend-scss.outputs.admin_passed }}"
SCSS_USER="${{ needs.frontend-scss.outputs.user_passed }}"
all_passed="true"
for check in "$PYLINT" "$RUFF" "$MYPY" "$ESLINT_ADMIN" "$ESLINT_USER" "$TS_ADMIN" "$TS_USER" "$SCSS_ADMIN" "$SCSS_USER"; do
if [ "$check" != "true" ]; then
all_passed="false"
break
fi
done
{
echo "## CI Results"
echo ""
echo "### Backend"
echo ""
echo "- $(check_icon $PYLINT) **Pylint** - $(status_text $PYLINT)"
echo "- $(check_icon $RUFF) **Ruff** - $(status_text $RUFF)"
echo "- $(check_icon $MYPY) **Mypy** - $(status_text $MYPY)"
echo ""
echo "### Frontend (user-app)"
echo ""
echo "- $(check_icon $ESLINT_USER) **ESLint** - $(status_text $ESLINT_USER)"
echo "- $(check_icon $TS_USER) **TypeScript** - $(status_text $TS_USER)"
echo "- $(check_icon $SCSS_USER) **SCSS** - $(status_text $SCSS_USER)"
echo ""
echo "### Frontend (admin-app)"
echo ""
echo "- $(check_icon $ESLINT_ADMIN) **ESLint** - $(status_text $ESLINT_ADMIN)"
echo "- $(check_icon $TS_ADMIN) **TypeScript** - $(status_text $TS_ADMIN)"
echo "- $(check_icon $SCSS_ADMIN) **SCSS** - $(status_text $SCSS_ADMIN)"
echo ""
if [ "$all_passed" == "true" ]; then
echo "---"
echo ""
echo "**All checks passed.**"
else
echo "---"
echo ""
echo "<details><summary>View failed check outputs</summary>"
echo ""
if [ "$PYLINT" != "true" ] && [ -f "artifacts/pylint-output/pylint-output.txt" ]; then
echo "#### Pylint"
echo ""
echo '```'
head -50 artifacts/pylint-output/pylint-output.txt
echo '```'
echo ""
fi
if [ "$RUFF" != "true" ] && [ -f "artifacts/ruff-output/ruff-output.txt" ]; then
echo "#### Ruff"
echo ""
echo '```'
head -50 artifacts/ruff-output/ruff-output.txt
echo '```'
echo ""
fi
if [ "$MYPY" != "true" ] && [ -f "artifacts/mypy-output/mypy-output.txt" ]; then
echo "#### Mypy"
echo ""
echo '```'
head -50 artifacts/mypy-output/mypy-output.txt
echo '```'
echo ""
fi
if [ "$ESLINT_USER" != "true" ] && [ -f "artifacts/eslint-user-app-output/eslint-output.txt" ]; then
echo "#### ESLint (user-app)"
echo ""
echo '```'
head -50 artifacts/eslint-user-app-output/eslint-output.txt
echo '```'
echo ""
fi
if [ "$ESLINT_ADMIN" != "true" ] && [ -f "artifacts/eslint-admin-app-output/eslint-output.txt" ]; then
echo "#### ESLint (admin-app)"
echo ""
echo '```'
head -50 artifacts/eslint-admin-app-output/eslint-output.txt
echo '```'
echo ""
fi
if [ "$TS_USER" != "true" ] && [ -f "artifacts/typescript-user-app-output/typescript-output.txt" ]; then
echo "#### TypeScript (user-app)"
echo ""
echo '```'
head -50 artifacts/typescript-user-app-output/typescript-output.txt
echo '```'
echo ""
fi
if [ "$TS_ADMIN" != "true" ] && [ -f "artifacts/typescript-admin-app-output/typescript-output.txt" ]; then
echo "#### TypeScript (admin-app)"
echo ""
echo '```'
head -50 artifacts/typescript-admin-app-output/typescript-output.txt
echo '```'
echo ""
fi
if [ "$SCSS_USER" != "true" ] && [ -f "artifacts/scss-user-app-output/scss-output.txt" ]; then
echo "#### SCSS (user-app)"
echo ""
echo '```'
head -50 artifacts/scss-user-app-output/scss-output.txt
echo '```'
echo ""
fi
if [ "$SCSS_ADMIN" != "true" ] && [ -f "artifacts/scss-admin-app-output/scss-output.txt" ]; then
echo "#### SCSS (admin-app)"
echo ""
echo '```'
head -50 artifacts/scss-admin-app-output/scss-output.txt
echo '```'
echo ""
fi
echo "</details>"
fi
echo ""
echo "<!-- ci-summary-marker -->"
} > summary.md
if [ "$all_passed" == "true" ]; then
echo "all_passed=true" >> $GITHUB_OUTPUT
else
echo "all_passed=false" >> $GITHUB_OUTPUT
fi
- name: Post PR Comment
uses: peter-evans/create-or-update-comment@v5
with:
issue-number: ${{ github.event.pull_request.number }}
body-path: summary.md
- name: Set final status
run: |
if [ "${{ steps.summary.outputs.all_passed }}" != "true" ]; then
echo "Some checks failed"
exit 1
fi