feat: improving PR experience with comments #37
This file contains 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: CI - Pull Request | |
on: pull_request | |
# Pull Request Runs on the same branch will be cancelled | |
concurrency: | |
group: ${{ github.head_ref }} | |
cancel-in-progress: true | |
jobs: | |
code-quality: | |
name: Check the code quality | |
runs-on: ubuntu-latest | |
timeout-minutes: 20 | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
ref: ${{ github.head_ref }} | |
- name: Setup node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: 18.x.x | |
cache: "npm" | |
- name: Install dependencies | |
id: install-dependencies | |
run: npm ci | |
- name: Store Playwright's Version | |
id: store-playwright-version | |
run: | | |
PLAYWRIGHT_VERSION=$(npm ls @playwright/test | grep @playwright | sed 's/.*@//') | |
echo "Playwright's Version: $PLAYWRIGHT_VERSION" | |
echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV | |
- name: Cache Playwright Browsers for Playwright's Version | |
id: cache-playwright-browsers | |
uses: actions/cache@v3 | |
env: | |
PLAYWRIGHT_VERSION: ${{ steps.store-playwright-version.outputs.PLAYWRIGHT_VERSION }} | |
if: env.PLAYWRIGHT_VERSION == 'true' | |
with: | |
path: ~/.cache/ms-playwright | |
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }} | |
- name: Install playwright browsers | |
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true' | |
run: npx playwright install --with-deps | |
- name: Run custom elements manifest analyzer | |
id: run-custom-elements-manifest-analyzer | |
run: npm run analyze | |
- name: Run eslint | |
id: run-eslint | |
run: npm run lint | |
- name: Run prettier | |
id: run-prettier | |
run: npm run prettier | |
- name: Run lit-analyzer | |
id: run-lit-analyzer | |
run: npm run lint:lit-analyzer | |
- name: Run tests and generate coverage | |
run: npm run test -- --coverage --debug | |
id: run-tests-and-generate-coverage | |
- name: Test tsdoc | |
run: npm run docs | |
id: test-tsdoc | |
- name: Check for modified files | |
id: git-check | |
run: echo "modified=$(if [ -n "$(git status --porcelain)" ]; then echo "true"; else echo "false"; fi)" >> $GITHUB_ENV | |
- name: Update changes in GitHub repository | |
id: update-changes-in-github-repository | |
env: | |
MODIFIED: ${{ steps.git-check.outputs.modified }} | |
if: env.MODIFIED == 'true' | |
run: | | |
git config --global user.name "github-actions" | |
git config --global user.email "[email protected]" | |
git add -A | |
git commit -m '[automated commit] lint format and import sort' | |
git push | |
- name: PR checks complete | |
if: always() | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const fs = require('fs'); | |
const steps = [ | |
{ name: 'Install dependencies', conclusion: '${{ steps.install-dependencies.outcome }}' }, | |
{ name: 'Custom elements manifest analyzer', conclusion: '${{ steps.run-custom-elements-manifest-analyzer.outcome }}' }, | |
{ name: 'Eslint', conclusion: '${{ steps.run-eslint.outcome }}' }, | |
{ name: 'Prettier', conclusion: '${{ steps.run-prettier.outcome }}' }, | |
{ name: 'Lit-analyzer', conclusion: '${{ steps.run-lit-analyzer.outcome }}' }, | |
{ name: 'Tests and coverage', conclusion: '${{ steps.run-tests-and-generate-coverage.outcome }}' }, | |
{ name: 'Test tsdoc', conclusion: '${{ steps.test-tsdoc.outcome }}' }, | |
{ name: 'Check for modified files', conclusion: '${{ steps.git-check.outcome }}' }, | |
{ name: 'Update changes in GitHub repository', conclusion: '${{ steps.update-changes-in-github-repository.outcome }}' } | |
] | |
const failedSteps = steps.filter(step => step.conclusion === 'failure'); | |
const skippedSteps = steps.filter(step => step.conclusion === 'skipped'); | |
const passedSteps = steps.filter(step => step.conclusion === 'success'); | |
const failedStepsDetails = failedSteps.map(step => `- ❌ - ${step.name} failed`).join('\n'); | |
const skippedStepsDetails = skippedSteps.map(step => `- ⏭️ - ${step.name} skipped`).join('\n'); | |
const passedStepsDetails = passedSteps.map(step => `- ✅ - ${step.name} passed`).join('\n'); | |
const coverage = fs.readFileSync("coverage/lcov-report/index.html", "utf8"); | |
const coverageData = coverage | |
.split('<table class="coverage-summary">') | |
.pop() | |
?.split("</table>")[0] | |
.replaceAll(/<a [^>]*>([^<]*)<\/a>/g, "$1") | |
.replaceAll(/<td[^>]*class="pic high"[^>]*>[^<]*<\/td>/g, "") | |
.replace('<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>', ""); | |
const commentBody = ` | |
## PR Checks Complete | |
${failedSteps.length > 0 ? `${failedStepsDetails}` : ''} | |
${skippedSteps.length > 0 ? `${skippedStepsDetails}` : ''} | |
${passedSteps.length > 0 ? `${passedStepsDetails}` : ''} | |
<details> | |
<summary> | |
📈 - Code Coverage: | |
</summary> | |
<table class="coverage-summary"> | |
${coverageData} | |
</table> | |
</details> | |
`; | |
const { data: comments } = await github.rest.issues.listComments({ | |
issue_number: context.issue.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo | |
}); | |
const comment = comments.find(comment => comment.body.includes('PR Checks Complete')); | |
if (comment) { | |
await github.rest.issues.updateComment({ | |
comment_id: comment.id, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: commentBody | |
}); | |
} else { | |
await github.rest.issues.createComment({ | |
issue_number: context.issue.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: commentBody | |
}); | |
} | |
generate-localizations: | |
name: Generate localizations. | |
needs: [code-quality] | |
timeout-minutes: 20 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.ref }} | |
- name: Setup node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: 18.x.x | |
cache: "npm" | |
- name: Install dependencies | |
run: npm ci | |
- name: Run lit-localize extract | |
run: npm run localize:extract | |
- name: Run lit-localize build | |
run: npm run localize:build | |
- name: Check diff | |
id: diff | |
run: git diff --quiet . || echo "changed=true" >> $GITHUB_OUTPUT | |
- name: Commit files | |
if: steps.diff.outputs.changed == 'true' | |
run: | | |
git config --global user.name 'github-actions' | |
git config --global user.email '[email protected]' | |
git add . | |
git commit -m "Generated locales" | |
git push | |
deploy-preview: | |
timeout-minutes: 20 | |
name: Deploy preview version of the storybook on firebase | |
needs: [generate-localizations] | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Setup node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: 18.x.x | |
cache: "npm" | |
- name: Install dependencies | |
run: npm ci | |
- name: Create custom-elements.json | |
run: npm run analyze | |
- name: Build storybook | |
run: npm run storybook:build | |
- uses: FirebaseExtended/action-hosting-deploy@v0 | |
with: | |
repoToken: "${{ secrets.GITHUB_TOKEN }}" | |
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_ZETA_DS }}" | |
expires: 7d | |
channelId: "pr-${{ github.event.number }}-${{ github.event.pull_request.head.ref }}" |