Prettier Code Format Check #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Prettier Code Format Check | |
| on: | |
| push: | |
| branches: [main, develop] | |
| paths: | |
| - "**/*.js" | |
| - "**/*.ts" | |
| - "**/*.jsx" | |
| - "**/*.tsx" | |
| - "**/*.css" | |
| - "**/*.json" | |
| - "**/*.md" | |
| - ".prettierrc" | |
| - ".prettierignore" | |
| - "package.json" | |
| - "package-lock.json" | |
| - "pnpm-lock.yaml" | |
| - "yarn.lock" | |
| pull_request: | |
| branches: [main, develop] | |
| paths: | |
| - "**/*.js" | |
| - "**/*.ts" | |
| - "**/*.jsx" | |
| - "**/*.tsx" | |
| - "**/*.css" | |
| - "**/*.json" | |
| - "**/*.md" | |
| - ".prettierrc" | |
| - ".prettierignore" | |
| - "package.json" | |
| - "package-lock.json" | |
| - "pnpm-lock.yaml" | |
| - "yarn.lock" | |
| workflow_dispatch: | |
| concurrency: | |
| group: prettier-check-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| prettier: | |
| name: 💅 Prettier Code Format Validation | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| env: | |
| # "true" => report-only (never fail) | |
| # "false" => enforce formatting (fail on violations) | |
| ALLOW_WARNINGS: "true" | |
| PRETTIER_REPORT: "prettier-report.txt" | |
| PRETTIER_SUMMARY: "prettier-summary.md" | |
| NPM_DEBUG_LOG: "npm-debug.log" | |
| # Enterprise behavior: | |
| # If Prettier is not installed in devDependencies, install a pinned version just for CI. | |
| # (You can later remove this and commit Prettier to package.json when ready.) | |
| BOOTSTRAP_PRETTIER_IF_MISSING: "true" | |
| PRETTIER_VERSION: "3.3.3" | |
| steps: | |
| - name: 📦 Checkout Repository | |
| uses: actions/checkout@v4 | |
| - name: ⚙️ Setup Node.js (LTS) | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: 🧾 Detect Package Manager | |
| id: pm | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ -f pnpm-lock.yaml ]]; then | |
| echo "manager=pnpm" >> "$GITHUB_OUTPUT" | |
| elif [[ -f yarn.lock ]]; then | |
| echo "manager=yarn" >> "$GITHUB_OUTPUT" | |
| elif [[ -f package-lock.json ]]; then | |
| echo "manager=npm" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "manager=npm" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: 📥 Install Dependencies (deterministic when possible) | |
| id: install | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mgr="${{ steps.pm.outputs.manager }}" | |
| if [[ "$mgr" == "pnpm" ]]; then | |
| corepack enable | |
| pnpm -v | |
| pnpm install --frozen-lockfile | |
| elif [[ "$mgr" == "yarn" ]]; then | |
| corepack enable | |
| yarn -v | |
| yarn install --frozen-lockfile | |
| else | |
| if [[ -f package-lock.json ]]; then | |
| npm ci | |
| else | |
| echo "::warning::No lockfile found. Falling back to 'npm install' (non-deterministic)." | |
| npm install | |
| fi | |
| fi | |
| - name: 🧰 Ensure Prettier Available (CI bootstrap) | |
| id: ensure-prettier | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ -x "node_modules/.bin/prettier" ]]; then | |
| echo "prettier_present=true" >> "$GITHUB_OUTPUT" | |
| echo "prettier_source=project" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [[ "${BOOTSTRAP_PRETTIER_IF_MISSING}" != "true" ]]; then | |
| echo "prettier_present=false" >> "$GITHUB_OUTPUT" | |
| echo "prettier_source=missing" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "::notice::Prettier not found in devDependencies. Bootstrapping Prettier v${PRETTIER_VERSION} for CI only." | |
| npm install --no-save "prettier@${PRETTIER_VERSION}" | |
| if [[ -x "node_modules/.bin/prettier" ]]; then | |
| echo "prettier_present=true" >> "$GITHUB_OUTPUT" | |
| echo "prettier_source=ci-bootstrap" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "prettier_present=false" >> "$GITHUB_OUTPUT" | |
| echo "prettier_source=bootstrap-failed" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: 🔍 Run Prettier | |
| id: prettier | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| report="${PRETTIER_REPORT}" | |
| prettier_present="${{ steps.ensure-prettier.outputs.prettier_present }}" | |
| if [[ "${prettier_present}" != "true" ]]; then | |
| echo "Prettier not available. Skipping formatting check." | |
| printf '%s\n' "Prettier not available in CI run." > "$report" | |
| echo "exit_code=2" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| set +e | |
| node_modules/.bin/prettier --check . > "$report" 2>&1 | |
| ec="$?" | |
| set -e | |
| echo "exit_code=$ec" >> "$GITHUB_OUTPUT" | |
| echo "Prettier exit code: $ec" | |
| - name: 🧾 Capture npm debug log (if any) | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if compgen -G "/home/runner/.npm/_logs/*-debug-0.log" > /dev/null; then | |
| latest="$(ls -t /home/runner/.npm/_logs/*-debug-0.log | head -n 1)" | |
| cp "$latest" "${NPM_DEBUG_LOG}" || true | |
| else | |
| echo "No npm debug log found." > "${NPM_DEBUG_LOG}" | |
| fi | |
| - name: 📄 Generate GitHub Job Summary | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| exit_code="${{ steps.prettier.outputs.exit_code }}" | |
| prettier_present="${{ steps.ensure-prettier.outputs.prettier_present }}" | |
| prettier_source="${{ steps.ensure-prettier.outputs.prettier_source }}" | |
| { | |
| echo "### 💅 Prettier Format Summary" | |
| echo | |
| echo "- **Ref:** \`${GITHUB_REF}\`" | |
| echo "- **Commit:** \`${GITHUB_SHA}\`" | |
| echo "- **Exit code:** \`${exit_code}\`" | |
| echo "- **ALLOW_WARNINGS:** \`${ALLOW_WARNINGS}\`" | |
| echo "- **Prettier available:** \`${prettier_present}\`" | |
| echo "- **Prettier source:** \`${prettier_source}\`" | |
| echo | |
| if [[ "${prettier_present}" != "true" ]]; then | |
| echo "⚠️ Prettier was not available. This run did not enforce formatting." | |
| echo | |
| echo "**Recommended fix (preferred):** commit Prettier into devDependencies:" | |
| echo | |
| echo '```bash' | |
| echo 'npm i -D prettier' | |
| echo '```' | |
| echo | |
| echo "**CI fallback used:** \`${BOOTSTRAP_PRETTIER_IF_MISSING}\` (version \`${PRETTIER_VERSION}\`)." | |
| echo | |
| elif [[ "$exit_code" != "0" ]]; then | |
| echo "⚠️ Formatting issues detected." | |
| echo | |
| echo "**Top 80 lines:**" | |
| echo | |
| echo '```text' | |
| head -n 80 "${PRETTIER_REPORT}" || true | |
| echo '```' | |
| echo | |
| echo "_Output truncated. Download artifacts for full report._" | |
| else | |
| echo "✅ No formatting issues found." | |
| fi | |
| } | tee "${PRETTIER_SUMMARY}" >> "$GITHUB_STEP_SUMMARY" | |
| - name: 📊 Upload Artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: prettier-format-report | |
| path: | | |
| ${{ env.PRETTIER_REPORT }} | |
| ${{ env.PRETTIER_SUMMARY }} | |
| ${{ env.NPM_DEBUG_LOG }} | |
| retention-days: 30 | |
| - name: ✅ Policy Gate (optional enforcement) | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ "${ALLOW_WARNINGS}" == "true" ]]; then | |
| echo "ALLOW_WARNINGS=true -> report-only mode. Passing." | |
| exit 0 | |
| fi | |
| prettier_present="${{ steps.ensure-prettier.outputs.prettier_present }}" | |
| exit_code="${{ steps.prettier.outputs.exit_code }}" | |
| if [[ "${prettier_present}" != "true" ]]; then | |
| echo "❌ Prettier is not available. Enforced mode requires it." | |
| exit 1 | |
| fi | |
| if [[ "$exit_code" != "0" ]]; then | |
| echo "❌ Failing due to Prettier formatting violations." | |
| exit 1 | |
| fi | |
| echo "✅ Prettier passed." |