brand(evig): finish the copy sweep — kill remaining old-tagline / non… #423
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: Deploy production app | |
| # Push to main → build + rsync to production app revampit.orangecat.ch. | |
| # One-time setup (Settings → Secrets → Actions): | |
| # HETZNER_SSH_PRIVATE_KEY — private key for ubuntu@167.233.22.31 | |
| # SELFHOST_ENV — full contents of .env.selfhost.local (multiline OK) | |
| # AUTH_TEST_USER_PASSWORD — non-admin E2E account (butaeff@gmail.com) | |
| # AUTH_TEST_ADMIN_PASSWORD — staff E2E account (georgy.butaev@revamp-it.ch) | |
| # Without deploy secrets the job logs a notice and exits cleanly. | |
| # Without E2E passwords the post-deploy inventory step is skipped. | |
| on: | |
| push: | |
| branches: [main] | |
| concurrency: | |
| group: deploy-selfhost-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| deploy: | |
| name: revampit.orangecat.ch | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| outputs: | |
| deployed: ${{ steps.mark-deployed.outputs.deployed }} | |
| env: | |
| HETZNER_SSH_PRIVATE_KEY: ${{ secrets.HETZNER_SSH_PRIVATE_KEY }} | |
| SELFHOST_ENV: ${{ secrets.SELFHOST_ENV }} | |
| steps: | |
| - name: Check secrets configured | |
| id: secrets | |
| run: | | |
| if [ -z "$HETZNER_SSH_PRIVATE_KEY" ] || [ -z "$SELFHOST_ENV" ]; then | |
| echo "::notice::HETZNER_SSH_PRIVATE_KEY and/or SELFHOST_ENV not set — skipping self-host deploy. Push from a machine with .env.selfhost.local still deploys via the pre-push hook." | |
| echo "configured=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "configured=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Checkout code | |
| if: steps.secrets.outputs.configured == 'true' | |
| uses: actions/checkout@v7 | |
| - name: Setup Node.js | |
| if: steps.secrets.outputs.configured == 'true' | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: npm | |
| - name: Install dependencies | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: npm ci | |
| # Persist Next.js's incremental compiler cache across runs. The build runs | |
| # on this ephemeral runner, so without this every build is COLD (full | |
| # recompile). restore-keys falls back to the latest cache for the same | |
| # lockfile, making subsequent builds incremental (warm). | |
| - name: Cache Next.js build | |
| if: steps.secrets.outputs.configured == 'true' | |
| uses: actions/cache@v4 | |
| with: | |
| path: .next/cache | |
| key: nextjs-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-${{ github.sha }} | |
| restore-keys: | | |
| nextjs-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- | |
| - name: Run ESLint | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: npm run lint | |
| - name: Type check | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: npm run typecheck | |
| - name: i18n structure gate | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: npm run test:i18n | |
| - name: Write selfhost env | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: | | |
| printf '%s' "$SELFHOST_ENV" > .env.selfhost.local | |
| chmod 600 .env.selfhost.local | |
| - name: Setup SSH | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: | | |
| mkdir -p ~/.ssh | |
| printf '%s\n' "$HETZNER_SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519 | |
| chmod 600 ~/.ssh/id_ed25519 | |
| ssh-keyscan -H 167.233.22.31 >> ~/.ssh/known_hosts | |
| - name: Deploy | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: bash scripts/selfhost-deploy-revampit.sh | |
| - name: Mark deployed | |
| id: mark-deployed | |
| if: steps.secrets.outputs.configured == 'true' | |
| run: echo "deployed=true" >> "$GITHUB_OUTPUT" | |
| post-deploy-smoke: | |
| name: Read-only prod smoke | |
| runs-on: ubuntu-latest | |
| needs: deploy | |
| if: needs.deploy.outputs.deployed == 'true' | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| # Read-only: public pages render + DB-backed public APIs return success. | |
| # No login, no prod mutation. The heavier authenticated dual-persona | |
| # journeys (which mutate prod) are manual: npm run test:e2e:inventory:prod. | |
| - name: Run read-only smoke (public pages + APIs) | |
| run: bash scripts/post-deploy-smoke.sh |