diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..58935d4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,63 @@ +name: CI + +on: + push: + branches: ["**"] + pull_request: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + env: + NEXT_TELEMETRY_DISABLED: "1" + DATABASE_URI: postgresql://ci:ci@localhost:5432/ci + PAYLOAD_SECRET: ci-only-not-a-real-secret + MEETING_SESSION_SECRET: ci-only-not-a-real-secret + ANALYTICS_SALT_SECRET: ci-only-not-a-real-secret + CRON_SECRET: ci-only-not-a-real-secret + NEXT_PUBLIC_SERVER_URL: http://localhost:3000 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Use Node.js 22 + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + - name: Install dependencies + run: npm ci + - name: Lint + run: npm run lint + - name: Typecheck + run: npx next typegen && npx tsc --noEmit + - name: Test + run: npm test + - name: Build + env: + NODE_ENV: production + run: npm run build + + build-image: + needs: test + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + runs-on: ubuntu-latest + permissions: + contents: read + env: + IMAGE: git.maro.run/maro/anouma + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Log in to registry + uses: docker/login-action@v3 + with: + registry: git.maro.run + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Build image + run: docker build -t "$IMAGE:$GITHUB_SHA" . + - name: Push image + run: docker push "$IMAGE:$GITHUB_SHA" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..943b5c1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,55 @@ +name: Release + +on: + push: + tags: ["v*.*.*"] + +permissions: + contents: read + +jobs: + promote-and-deploy: + runs-on: ubuntu-latest + env: + IMAGE: git.maro.run/maro/anouma + steps: + - name: Log in to registry + uses: docker/login-action@v3 + with: + registry: git.maro.run + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Pull tested image + run: docker pull "$IMAGE:$GITHUB_SHA" + - name: Promote release image + env: + VERSION: ${{ github.ref_name }} + run: | + docker tag "$IMAGE:$GITHUB_SHA" "$IMAGE:$VERSION" + docker tag "$IMAGE:$GITHUB_SHA" "$IMAGE:latest" + docker push "$IMAGE:$VERSION" + docker push "$IMAGE:latest" + - name: Deploy to production + env: + DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} + DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }} + DEPLOY_USER: ${{ secrets.DEPLOY_USER }} + DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} + DEPLOY_HOST_KEY: ${{ secrets.DEPLOY_HOST_KEY }} + VERSION: ${{ github.ref_name }} + shell: bash + run: | + set -euo pipefail + umask 077 + key_file="$(mktemp)" + known_hosts_file="$(mktemp)" + trap 'rm -f "$key_file" "$known_hosts_file"' EXIT + printf '%s\n' "$DEPLOY_SSH_KEY" > "$key_file" + chmod 600 "$key_file" + if [ -n "${DEPLOY_HOST_KEY:-}" ]; then + printf '%s\n' "$DEPLOY_HOST_KEY" > "$known_hosts_file" + else + ssh-keyscan -p "${DEPLOY_PORT:-22}" "$DEPLOY_HOST" > "$known_hosts_file" 2>/dev/null + fi + ssh -i "$key_file" -o UserKnownHostsFile="$known_hosts_file" -p "${DEPLOY_PORT:-22}" \ + "${DEPLOY_USER}@${DEPLOY_HOST}" "deploy ${VERSION}"