diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml deleted file mode 100644 index dcdeb98..0000000 --- a/.gitea/workflows/ci.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: CI - Quality Assurance - -on: - pull_request: - -jobs: - qa: - name: ๐Ÿงช QA - runs-on: docker - container: - image: catthehacker/ubuntu:act-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - name: Setup pnpm - uses: pnpm/action-setup@v3 - with: - version: 10 - - name: ๐Ÿ” Registry Auth - run: | - echo "@mintel:registry=https://${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}" > .npmrc - echo "//${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}/:_authToken=${{ secrets.REGISTRY_PASS }}" >> .npmrc - - name: Install dependencies - run: pnpm install --frozen-lockfile - - name: ๐Ÿงช Parallel Checks - run: | - pnpm lint & - pnpm build & - wait diff --git a/.gitea/workflows/qa.yml b/.gitea/workflows/qa.yml new file mode 100644 index 0000000..ec895d7 --- /dev/null +++ b/.gitea/workflows/qa.yml @@ -0,0 +1,188 @@ +name: Nightly QA + +on: + push: + branches: [main] + schedule: + - cron: "0 3 * * *" + workflow_dispatch: + +env: + TARGET_URL: "https://testing.mintel.me" + PROJECT_NAME: "mintel.me" + +jobs: + # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + # 1. Performance (Lighthouse) + # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + lighthouse: + name: ๐ŸŽญ Lighthouse + runs-on: docker + container: + image: catthehacker/ubuntu:act-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: ๐Ÿ” Registry Auth + run: | + echo "Testing available secrets against git.infra.mintel.me Docker registry..." + TOKENS="${{ secrets.GITHUB_TOKEN }} ${{ secrets.GITEA_PAT }} ${{ secrets.MINTEL_PRIVATE_TOKEN }} ${{ secrets.NPM_TOKEN }}" + USERS="${{ github.repository_owner }} ${{ github.actor }} marcmintel mintel mmintel" + + for T_RAW in $TOKENS; do + if [ -n "$T_RAW" ]; then + T=$(echo "$T_RAW" | tr -d ' ' | tr -d '\n' | tr -d '\r') + for U in $USERS; do + if [ -n "$U" ]; then + if echo "$T" | docker login git.infra.mintel.me -u "$U" --password-stdin > /dev/null 2>&1; then + echo "โœ… Successfully authenticated with a token." + echo "@mintel:registry=https://git.infra.mintel.me/api/packages/mmintel/npm/" > .npmrc + echo "//git.infra.mintel.me/api/packages/mmintel/npm/:_authToken=${T}" >> .npmrc + echo "always-auth=true" >> .npmrc + break 2 + fi + fi + done + fi + done + - name: ๐Ÿ“ฆ Cache node_modules + uses: actions/cache@v4 + id: cache-deps + with: + path: node_modules + key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + pnpm store prune + pnpm install --no-frozen-lockfile + - name: ๐ŸŒ Install Chrome & Dependencies + run: | + apt-get update && apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libasound2t64 libpango-1.0-0 libcairo2 + npx puppeteer browsers install chrome + - name: ๐ŸŽญ Desktop + continue-on-error: true + env: + NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} + GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} + PAGESPEED_LIMIT: 5 + run: pnpm --filter @mintel/web run pagespeed:test -- --collect.settings.preset=desktop + - name: ๐Ÿ“ฑ Mobile + continue-on-error: true + env: + NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} + GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} + PAGESPEED_LIMIT: 5 + run: pnpm --filter @mintel/web run pagespeed:test -- --collect.settings.preset=mobile + + # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + # 2. E2E & Links + # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + e2e: + name: ๐Ÿ“ E2E & Links + runs-on: docker + container: + image: catthehacker/ubuntu:act-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: ๐Ÿ” Registry Auth + run: | + echo "Testing available secrets against git.infra.mintel.me Docker registry..." + TOKENS="${{ secrets.GITHUB_TOKEN }} ${{ secrets.GITEA_PAT }} ${{ secrets.MINTEL_PRIVATE_TOKEN }} ${{ secrets.NPM_TOKEN }}" + USERS="${{ github.repository_owner }} ${{ github.actor }} marcmintel mintel mmintel" + + for T_RAW in $TOKENS; do + if [ -n "$T_RAW" ]; then + T=$(echo "$T_RAW" | tr -d ' ' | tr -d '\n' | tr -d '\r') + for U in $USERS; do + if [ -n "$U" ]; then + if echo "$T" | docker login git.infra.mintel.me -u "$U" --password-stdin > /dev/null 2>&1; then + echo "โœ… Successfully authenticated with a token." + echo "@mintel:registry=https://git.infra.mintel.me/api/packages/mmintel/npm/" > .npmrc + echo "//git.infra.mintel.me/api/packages/mmintel/npm/:_authToken=${T}" >> .npmrc + echo "always-auth=true" >> .npmrc + break 2 + fi + fi + done + fi + done + - name: ๐Ÿ“ฆ Cache node_modules + uses: actions/cache@v4 + id: cache-deps + with: + path: node_modules + key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + pnpm store prune + pnpm install --no-frozen-lockfile + - name: ๐ŸŒ Install Chrome & Dependencies + run: | + apt-get update && apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libasound2t64 libpango-1.0-0 libcairo2 + npx puppeteer browsers install chrome + - name: ๐Ÿ“ E2E Form Submission Test + env: + NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} + GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} + PUPPETEER_EXECUTABLE_PATH: /usr/bin/chromium + run: pnpm --filter @mintel/web run check:forms + - name: ๐Ÿ–ผ๏ธ OG Images Check + continue-on-error: true + env: + TEST_URL: ${{ env.TARGET_URL }} + run: pnpm --filter @mintel/web run check:og + - name: ๐Ÿ”— Internal Links Test + continue-on-error: true + env: + NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} + GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} + run: pnpm --filter @mintel/web run test:links || true + + # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + # 3. Notification + # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + notify: + name: ๐Ÿ”” Notify + needs: [lighthouse, e2e] + if: always() + runs-on: docker + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: ๐Ÿ”” Gotify + shell: bash + run: | + LIGHTHOUSE="${{ needs.lighthouse.result }}" + E2E="${{ needs.e2e.result }}" + + if [[ "$LIGHTHOUSE" != "success" || "$E2E" != "success" ]]; then + PRIORITY=8 + EMOJI="๐Ÿšจ" + STATUS="Failed" + else + PRIORITY=2 + EMOJI="โœ…" + STATUS="Passed" + fi + + TITLE="$EMOJI ${{ env.PROJECT_NAME }} QA $STATUS" + MESSAGE="Lighthouse: $LIGHTHOUSE | E2E: $E2E + ${{ env.TARGET_URL }}" + + curl -s -k -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \ + -F "title=$TITLE" \ + -F "message=$MESSAGE" \ + -F "priority=$PRIORITY" || true