From 9a5508ffe88d3ec9c169c3acb542f80cd82824fa Mon Sep 17 00:00:00 2001 From: ianshaloom Date: Fri, 21 Nov 2025 14:23:50 +0300 Subject: [PATCH] chore: update .gitignore to include Gitea workflow files - Added .gitea/workflows/deploy.yml and .gitea/workflows/build.yml to .gitignore to prevent tracking of workflow configuration files. --- .gitea/workflows/README.md | 168 +++++++++++++++++++++++++++++++++++++ .gitea/workflows/test.yml | 75 +++++++++++++++++ .gitignore | 2 + 3 files changed, 245 insertions(+) create mode 100644 .gitea/workflows/README.md create mode 100644 .gitea/workflows/test.yml diff --git a/.gitea/workflows/README.md b/.gitea/workflows/README.md new file mode 100644 index 0000000..67a2090 --- /dev/null +++ b/.gitea/workflows/README.md @@ -0,0 +1,168 @@ +# Gitea Workflows + +This directory contains Gitea Actions workflows for CI/CD. + +## Workflows + +### `build.yml` - Build Application Image + +Builds the application image using Cloud Native Buildpacks. + +**Triggers:** +- Push to `main`, `production`, or `develop` branches +- Pull requests to `main` or `production` +- Manual workflow dispatch + +**Outputs:** +- Docker image (tagged and optionally pushed to registry) +- Image artifact (if no registry configured) + +### `deploy.yml` - Deploy to Production + +Deploys the built image to production server. + +**Triggers:** +- After successful `build.yml` workflow completion +- Manual workflow dispatch (with image tag input) + +**Process:** +- Downloads image artifact or pulls from registry +- Transfers deployment files to production server +- Mounts Firebase credentials securely +- Starts container and verifies health + +### `test.yml` - Run Tests + +Runs Go tests and linting. + +**Triggers:** +- Push to `main` or `develop` branches +- Pull requests to `main` or `develop` + +**Jobs:** +- `test` - Runs Go tests with coverage +- `lint` - Runs golangci-lint + +#### Triggers + +- Push to `main` or `production` branches (when `backend/**` files change) +- Manual workflow dispatch with environment selection + +## Workflow Flow + +``` +Push to main/production + ↓ +[build.yml] → Builds image → Pushes to registry (optional) + ↓ +[deploy.yml] → Deploys to production → Verifies health +``` + +**Manual Deployment:** +1. Run `build.yml` manually (or wait for push) +2. Run `deploy.yml` manually with image tag + +#### Required Secrets + +Configure these secrets in Gitea repository settings: + +**Build Secrets:** +- `FRONTEND_URL` - Frontend application URL +- `DB_HOST` - Database host +- `DB_PORT` - Database port +- `DB_USER` - Database username +- `DB_PASSWORD` - Database password +- `DB_NAME` - Database name +- `FIREBASE_PROJECT_ID` - Firebase project ID +- `FIREBASE_STORAGE_BUCKET` - Firebase storage bucket name + +**Deployment Secrets:** +- `DEPLOY_HOST` - Production server hostname/IP +- `DEPLOY_USER` - SSH user for deployment +- `DEPLOY_PATH` - Deployment directory on server +- `SSH_PRIVATE_KEY` - SSH private key for server access +- `SSH_KNOWN_HOSTS` - SSH known hosts entry +- `FIREBASE_CREDENTIALS_FILE_PATH` - Path to Firebase credentials file on server +- `PORT` - Application port (default: 8080) + +**Optional Secrets:** +- `REGISTRY_URL` - Container registry URL (if using registry) +- `REGISTRY_USERNAME` - Registry username +- `REGISTRY_PASSWORD` - Registry password +- `NOTIFICATION_WEBHOOK` - Webhook URL for deployment notifications + +#### Security Considerations + +1. **Firebase Credentials:** + - Credentials are **NOT** included in the build + - Credentials are mounted at runtime on the production server + - File must exist on production server at path specified in `FIREBASE_CREDENTIALS_FILE_PATH` + - Mounted with read-only and SELinux shared context (`:ro,z`) + +2. **Database Credentials:** + - Stored as Gitea secrets + - Passed as environment variables at runtime + - Never committed to repository + +3. **SSH Access:** + - Uses SSH key authentication + - Private key stored as Gitea secret + - Known hosts verified + +#### Deployment Process + +1. **Build Phase:** + - Checks out code + - Sets up Docker and Pack CLI + - Configures Docker socket (handles rootless Docker) + - Builds image using Pack with `--docker-host` flag + - Tags and optionally pushes to registry + +2. **Deploy Phase:** + - Transfers deployment files to production server + - Transfers image (if not using registry) + - Creates `.env.production` on server + - Runs deployment script that: + - Stops existing container + - Mounts Firebase credentials (read-only) + - Starts new container + - Verifies deployment with health check + - Rolls back on failure + +#### Manual Deployment + +To trigger manual deployment: + +1. Go to Gitea repository → Actions → Workflows +2. Select "Production Deployment" +3. Click "Run workflow" +4. Select environment (production/staging) +5. Click "Run workflow" + +#### Troubleshooting + +**Build fails with Docker permission error:** +- Ensure Docker socket is accessible +- Check `PACK_DOCKER_HOST` is set correctly +- Verify `--docker-host` flag is being passed to pack + +**Deployment fails with Firebase credentials error:** +- Verify credentials file exists on server at specified path +- Check file permissions: `chmod 644 firebase-credentials.json` +- Ensure SELinux allows access (use `:z` flag in mount) + +**SSH connection fails:** +- Verify SSH key is correct +- Check known hosts entry +- Ensure user has access to deployment directory + +**Health check fails:** +- Check container logs: `podman logs jd-book-uploader` +- Verify port is accessible +- Check firewall rules + +## Related Documentation + +- `../../deployment/docs/pack-docker-permissions-fix.md` - Pack Docker permissions fix +- `../../deployment/docs/secrets-management.md` - Secrets management guide + diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 0000000..8110504 --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,75 @@ +name: Run Tests + +on: + push: + branches: + - main + - production + - develop + paths: + - 'backend/**' + pull_request: + branches: + - main + - production + - develop + paths: + - 'backend/**' + +jobs: + test: + name: Run Go Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.25' + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Install dependencies + working-directory: backend + run: go mod download + + - name: Run tests + working-directory: backend + run: go test -v -race -coverprofile=coverage.out ./... + + - name: Upload coverage + uses: codecov/codecov-action@v4 + if: always() + with: + file: ./backend/coverage.out + flags: backend + name: backend-coverage + + lint: + name: Lint Code + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.25' + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v4 + with: + version: latest + working-directory: backend + diff --git a/.gitignore b/.gitignore index a271b25..09731f3 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ build/ .env.production .env.local .env.production.example +.gitea/workflows/deploy.yml +.gitea/workflows/build.yml