Feature/103 #155
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 | |
on: | |
pull_request: | |
branches: [main] | |
push: | |
branches: [main] | |
env: | |
CACHED_DEPENDENCY_PATHS: | | |
${{ github.workspace }}/.yarn/cache | |
${{ github.workspace }}/.yarn/unplugged | |
CACHED_BUILD_PATHS: ${{ github.workspace }}/.next | |
BUILD_CACHE_KEY: ${{ github.sha }} | |
DEFAULT_NODE_VERSION: '18' | |
jobs: | |
job_install_dependencies: | |
name: Install Dependencies | |
runs-on: ubuntu-latest | |
timeout-minutes: 15 | |
steps: | |
- name: Check out current commit (${{ github.sha }}) | |
uses: actions/checkout@v3 | |
- name: Set up Node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.DEFAULT_NODE_VERSION }} | |
- name: Create env file | |
run: | | |
touch .env | |
echo NEXT_PUBLIC_API_URL = ${{ secrets.NEXT_PUBLIC_API_URL }} >> .env | |
echo NEXTAUTH_SECRET = ${{ secrets.NEXTAUTH_SECRET }} >> .env | |
echo NEXTAUTH_URL = ${{ secrets.NEXTAUTH_URL }} >> .env | |
echo NEXT_PUBLIC_APP_FCM_API_KEY = ${{ secrets.NEXT_PUBLIC_APP_FCM_API_KEY }} >> .env | |
echo NEXT_PUBLIC_APP_FCM_VAPID_KEY = ${{ secrets.NEXT_PUBLIC_APP_FCM_VAPID_KEY }} >> .env | |
cat .env | |
- name: Compute dependency cache key | |
id: compute_lockfile_hash | |
run: echo "hash=${{ hashFiles('yarn.lock') }}" >> $GITHUB_OUTPUT | |
- name: Check dependency cache | |
uses: actions/cache@v3 | |
id: cache_dependencies | |
with: | |
path: ${{ env.CACHED_DEPENDENCY_PATHS }} | |
key: ${{ steps.compute_lockfile_hash.outputs.hash }} | |
- name: Install dependencies | |
if: steps.cache_dependencies.outputs.cache-hit == '' | |
run: yarn install --immutable | |
outputs: | |
dependency_cache_key: ${{ steps.compute_lockfile_hash.outputs.hash }} | |
job_build: | |
name: Build | |
needs: [job_install_dependencies] | |
runs-on: ubuntu-latest | |
timeout-minutes: 15 | |
steps: | |
- name: Check out current commit (${{ github.sha }}) | |
uses: actions/checkout@v3 | |
- name: Set up Node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.DEFAULT_NODE_VERSION }} | |
- name: Check dependency cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_DEPENDENCY_PATHS }} | |
key: ${{ needs.job_install_dependencies.outputs.dependency_cache_key }} | |
- name: Check build cache | |
uses: actions/cache@v3 | |
id: cache_built_packages | |
with: | |
path: ${{ env.CACHED_BUILD_PATHS }} | |
key: ${{ env.BUILD_CACHE_KEY }} | |
- name: Build | |
if: steps.cache_built_packages.outputs.cache-hit == '' | |
run: yarn build | |
outputs: | |
dependency_cache_key: ${{ needs.job_install_dependencies.outputs.dependency_cache_key }} | |
job_continuous_integration: | |
name: check unit test & lint | |
runs-on: ubuntu-latest | |
needs: [ job_install_dependencies ] | |
steps: | |
- name: Check out current commit (${{ github.sha }}) | |
uses: actions/checkout@v3 | |
- name: Set up Node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.DEFAULT_NODE_VERSION }} | |
- name: Check dependency cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_DEPENDENCY_PATHS }} | |
key: ${{ needs.job_install_dependencies.outputs.dependency_cache_key }} | |
- name: Check Lint | |
if: github.event_name != 'push' | |
run: yarn lint | |
- name: Check Unit Test | |
if: github.event_name != 'push' | |
run: yarn test:unit | |
job_codecov_test_coverage: | |
name: Set Codecov unit test coverage | |
runs-on: ubuntu-latest | |
needs: [ job_install_dependencies ] | |
steps: | |
- name: Check out current commit (${{ github.sha }}) | |
uses: actions/checkout@v3 | |
- name: Set up Node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.DEFAULT_NODE_VERSION }} | |
- name: Check dependency cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_DEPENDENCY_PATHS }} | |
key: ${{ needs.job_install_dependencies.outputs.dependency_cache_key }} | |
- name: Create Unit Test Coverage | |
run: yarn test:coverage | |
- name: Set unit test coverage | |
uses: codecov/codecov-action@v2 | |
with: | |
token: ${{ secrets.CODECOV_TOKEN }} | |
fail_ci_if_error: true | |
job_check_e2e_test: | |
name: check e2e test | |
if: github.event_name != 'push' | |
needs: [ job_install_dependencies ] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check out current commit (${{ github.sha }}) | |
uses: actions/checkout@v3 | |
- name: Set up Node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.DEFAULT_NODE_VERSION }} | |
- name: Check dependency cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_DEPENDENCY_PATHS }} | |
key: ${{ needs.job_install_dependencies.outputs.dependency_cache_key }} | |
- name: Install dependencies | |
run: yarn install --immutable | |
- name: Enable Plug-n-Play | |
run: yarn cypress:pnp | |
- name: Cypress run | |
uses: cypress-io/github-action@v4 | |
with: | |
install: false | |
browser: chrome | |
record: true | |
headed: true | |
config-file: cypress.config.js | |
start: yarn dev | |
command-prefix: yarn dlx | |
env: | |
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} | |
CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
job_nextjs_bundle_analysis: | |
name: Next.js bundle analysis | |
runs-on: ubuntu-latest | |
needs: [job_build] | |
steps: | |
- name: Check out current commit (${{ github.sha }}) | |
uses: actions/checkout@v3 | |
- name: Set up Node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.DEFAULT_NODE_VERSION }} | |
- name: Check dependency cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_DEPENDENCY_PATHS }} | |
key: ${{ needs.job_build.outputs.dependency_cache_key }} | |
- name: Check build cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_BUILD_PATHS }} | |
key: ${{ env.BUILD_CACHE_KEY }} | |
- name: Analyze Bundle Sizes | |
uses: transferwise/actions-next-bundle-analyzer@master | |
with: | |
workflow-id: ci.yml | |
base-branch: main | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
job_lhci: | |
name: Lighthouse CI | |
if: github.event_name != 'push' | |
needs: [ job_build ] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check out current commit (${{ github.sha }}) | |
uses: actions/checkout@v3 | |
- name: Set up Node | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.DEFAULT_NODE_VERSION }} | |
- name: Check dependency cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_DEPENDENCY_PATHS }} | |
key: ${{ needs.job_build.outputs.dependency_cache_key }} | |
- name: Check build cache | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.CACHED_BUILD_PATHS }} | |
key: ${{ env.BUILD_CACHE_KEY }} | |
- name: Install @lhci/cli dependencies | |
run: yarn install | |
- name: Run Lighthouse CI | |
env: | |
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }} | |
run: yarn lhci autorun || echo "Fail to Run Lighthouse CI!" | |
- name: Format lighthouse score | |
id: format_lighthouse_score | |
uses: actions/github-script@v6 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const fs = require('fs'); | |
const results = JSON.parse(fs.readFileSync('${{ github.workspace }}/lhci_reports/manifest.json')); | |
let comments = ''; | |
results.forEach((result, index) => { | |
const { summary, jsonPath } = result; | |
const details = JSON.parse(fs.readFileSync(jsonPath)); | |
const { audits } = details; | |
const formatResult = (res) => Math.round(res * 100); | |
Object.keys(summary).forEach((key) => { | |
summary[key] = formatResult(summary[key]); | |
}); | |
const score = (res) => { | |
if (res >= 90) { | |
return '🟢'; | |
} | |
if (res >= 50) { | |
return '🟠'; | |
} | |
return '🔴'; | |
}; | |
const comment = [ | |
`⚡️ ${index + 1} Lighthouse report!`, | |
'| Category | Score |', | |
'| --- | --- |', | |
`| ${score(summary.performance)} Performance | ${summary.performance} |`, | |
`| ${score(summary.accessibility)} Accessibility | ${summary.accessibility} |`, | |
`| ${score(summary['best-practices'])} Best Practices | ${summary['best-practices']} |`, | |
`| ${score(summary.seo)} SEO | ${summary.seo} |`, | |
`| ${score(summary.pwa)} PWA | ${summary.pwa} |`, | |
].join('\n'); | |
const detail = [ | |
'| Category | Score |', | |
'| --- | --- |', | |
`| ${score(audits['first-contentful-paint'].score * 100)} First Contentful Paint | ${audits['first-contentful-paint'].displayValue} |`, | |
`| ${score(audits.interactive.score * 100)} Time to Interactive | ${audits.interactive.displayValue} |`, | |
`| ${score(audits['speed-index'].score * 100)} Speed Index | ${audits['speed-index'].displayValue} |`, | |
`| ${score(audits['total-blocking-time'].score * 100)} Total Blocking Time | ${audits['total-blocking-time'].displayValue} |`, | |
`| ${score(audits['largest-contentful-paint'].score * 100)} Largest Contentful Paint | ${audits['largest-contentful-paint'].displayValue} |`, | |
`| ${score(audits['cumulative-layout-shift'].score * 100)} Cumulative Layout Shift | ${audits['cumulative-layout-shift'].displayValue} |`, | |
].join('\n'); | |
comments += `${comment}\n\n${detail}\n\n`; | |
}); | |
core.setOutput('comments', comments); | |
- name: comment PR | |
uses: unsplash/[email protected] | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
msg: ${{ steps.format_lighthouse_score.outputs.comments }} | |
check_for_duplicate_msg: false |