Generated by Spark: GitHub/gitlab/Jenkins/circleci ci cd config

This commit is contained in:
2026-01-16 02:25:22 +00:00
committed by GitHub
parent 7de782ec62
commit c63810bca1
12 changed files with 2034 additions and 3 deletions

264
.circleci/config.yml Normal file
View File

@@ -0,0 +1,264 @@
version: 2.1
orbs:
node: circleci/node@5.2.0
docker: circleci/docker@2.6.0
slack: circleci/slack@4.13.3
executors:
node-executor:
docker:
- image: cimg/node:20.11
resource_class: large
working_directory: ~/repo
playwright-executor:
docker:
- image: mcr.microsoft.com/playwright:v1.42.0-focal
resource_class: large
working_directory: ~/repo
commands:
restore-dependencies:
description: 'Restore npm dependencies from cache'
steps:
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package-lock.json" }}
- v1-dependencies-
save-dependencies:
description: 'Save npm dependencies to cache'
steps:
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package-lock.json" }}
notify-slack-on-fail:
description: 'Notify Slack on failure'
steps:
- slack/notify:
event: fail
template: basic_fail_1
notify-slack-on-success:
description: 'Notify Slack on success'
steps:
- slack/notify:
event: pass
template: success_tagged_deploy_1
jobs:
lint:
executor: node-executor
steps:
- checkout
- restore-dependencies
- run:
name: Install dependencies
command: npm ci
- save-dependencies
- run:
name: Run ESLint
command: npm run lint || echo "No lint script found"
- run:
name: TypeScript type check
command: npx tsc --noEmit
- notify-slack-on-fail
test:
executor: node-executor
steps:
- checkout
- restore-dependencies
- run:
name: Install dependencies
command: npm ci
- save-dependencies
- run:
name: Run unit tests
command: npm test || echo "No test script found"
- store_test_results:
path: ./junit.xml
- store_artifacts:
path: coverage
destination: coverage
- notify-slack-on-fail
build:
executor: node-executor
steps:
- checkout
- restore-dependencies
- run:
name: Install dependencies
command: npm ci
- save-dependencies
- run:
name: Build application
command: npm run build
- persist_to_workspace:
root: .
paths:
- dist
- store_artifacts:
path: dist
destination: build
- notify-slack-on-fail
e2e-test:
executor: playwright-executor
steps:
- checkout
- restore-dependencies
- run:
name: Install dependencies
command: npm ci
- save-dependencies
- attach_workspace:
at: .
- run:
name: Install Playwright browsers
command: npx playwright install chromium
- run:
name: Run E2E tests
command: npm run test:e2e || echo "No E2E tests configured"
- store_test_results:
path: playwright-report
- store_artifacts:
path: playwright-report
destination: e2e-report
- notify-slack-on-fail
security-scan:
executor: node-executor
steps:
- checkout
- restore-dependencies
- run:
name: Install dependencies
command: npm ci
- save-dependencies
- run:
name: Run npm audit
command: npm audit --audit-level=moderate || true
- run:
name: Install Trivy
command: |
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy -y
- run:
name: Run Trivy scan
command: trivy fs --exit-code 0 --no-progress --format json --output trivy-report.json .
- store_artifacts:
path: trivy-report.json
destination: security/trivy-report.json
- notify-slack-on-fail
docker-build-and-push:
executor: docker/docker
steps:
- checkout
- setup_remote_docker:
docker_layer_caching: true
- attach_workspace:
at: .
- run:
name: Build Docker image
command: |
docker build -t ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:$CIRCLE_BRANCH .
docker tag ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:$CIRCLE_BRANCH \
ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:$CIRCLE_BRANCH-$CIRCLE_SHA1
- run:
name: Push to registry
command: |
echo $DOCKER_PASSWORD | docker login ghcr.io -u $DOCKER_USERNAME --password-stdin
docker push ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:$CIRCLE_BRANCH
docker push ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:$CIRCLE_BRANCH-$CIRCLE_SHA1
if [ "$CIRCLE_BRANCH" = "main" ]; then
docker tag ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:$CIRCLE_BRANCH \
ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:latest
docker push ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:latest
fi
- notify-slack-on-fail
deploy-staging:
executor: node-executor
steps:
- checkout
- run:
name: Deploy to staging
command: |
echo "Deploying to staging environment..."
echo "Image: ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:develop-$CIRCLE_SHA1"
curl -X POST $STAGING_WEBHOOK_URL \
-H "Content-Type: application/json" \
-d "{\"image\":\"ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:develop\",\"sha\":\"$CIRCLE_SHA1\"}"
- notify-slack-on-success
- notify-slack-on-fail
deploy-production:
executor: node-executor
steps:
- checkout
- run:
name: Deploy to production
command: |
echo "Deploying to production environment..."
echo "Image: ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:latest"
curl -X POST $PRODUCTION_WEBHOOK_URL \
-H "Content-Type: application/json" \
-d "{\"image\":\"ghcr.io/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:latest\",\"sha\":\"$CIRCLE_SHA1\"}"
- notify-slack-on-success
- notify-slack-on-fail
workflows:
version: 2
build-test-deploy:
jobs:
- lint
- test:
requires:
- lint
- build:
requires:
- test
- e2e-test:
requires:
- build
- security-scan:
requires:
- build
- docker-build-and-push:
requires:
- build
- test
- security-scan
filters:
branches:
only:
- main
- develop
- deploy-staging:
requires:
- docker-build-and-push
filters:
branches:
only: develop
- hold-for-approval:
type: approval
requires:
- docker-build-and-push
- e2e-test
filters:
branches:
only: main
- deploy-production:
requires:
- hold-for-approval
filters:
branches:
only: main

20
.dockerignore Normal file
View File

@@ -0,0 +1,20 @@
node_modules
npm-debug.log
dist
.git
.github
.gitignore
.dockerignore
Dockerfile
docker-compose.yml
*.md
coverage
.env
.env.local
.env.*.local
playwright-report
test-results
.vscode
.idea
*.log
.DS_Store

241
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,241 @@
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
env:
NODE_VERSION: '20.x'
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint --if-present || echo "No lint script found"
- name: Type check
run: npx tsc --noEmit
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm test --if-present || echo "No test script found"
- name: Upload coverage reports
uses: codecov/codecov-action@v4
if: always()
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/coverage-final.json
flags: unittests
fail_ci_if_error: false
build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 7
e2e-tests:
name: E2E Tests
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Run E2E tests
run: npm run test:e2e --if-present || echo "No E2E tests configured"
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 7
security-scan:
name: Security Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run npm audit
run: npm audit --audit-level=moderate || true
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'
docker-build:
name: Build Docker Image
runs-on: ubuntu-latest
needs: [lint, test, build]
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: [docker-build]
if: github.ref == 'refs/heads/develop'
environment:
name: staging
url: https://staging.codeforge.example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: |
echo "Deploying to staging environment..."
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop-${{ github.sha }}"
- name: Notify deployment
uses: 8398a7/action-slack@v3
if: always()
with:
status: ${{ job.status }}
text: 'Staging deployment ${{ job.status }}'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [docker-build, e2e-tests]
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://codeforge.example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: |
echo "Deploying to production environment..."
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-${{ github.sha }}"
- name: Notify deployment
uses: 8398a7/action-slack@v3
if: always()
with:
status: ${{ job.status }}
text: 'Production deployment ${{ job.status }}'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

87
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,87 @@
name: Release
on:
push:
tags:
- 'v*'
env:
NODE_VERSION: '20.x'
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
release:
name: Create Release
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Create ZIP archive
run: |
cd dist
zip -r ../codeforge-${{ github.ref_name }}.zip .
cd ..
- name: Generate changelog
id: changelog
run: |
echo "## Changes" > CHANGELOG.md
git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s (%h)" >> CHANGELOG.md
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: codeforge-${{ github.ref_name }}.zip
body_path: CHANGELOG.md
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
labels: |
org.opencontainers.image.title=CodeForge
org.opencontainers.image.description=Low-Code Next.js App Builder
org.opencontainers.image.version=${{ steps.version.outputs.VERSION }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
cache-from: type=gha
cache-to: type=gha,mode=max

177
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,177 @@
stages:
- lint
- test
- build
- security
- docker
- deploy
variables:
NODE_VERSION: '20'
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: '/certs'
NPM_CONFIG_CACHE: '$CI_PROJECT_DIR/.npm'
REGISTRY: '$CI_REGISTRY_IMAGE'
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
- .npm/
.node_template: &node_template
image: node:${NODE_VERSION}-alpine
before_script:
- node --version
- npm --version
- npm ci --cache .npm --prefer-offline
lint:eslint:
<<: *node_template
stage: lint
script:
- npm run lint || echo "No lint script found"
allow_failure: false
lint:typecheck:
<<: *node_template
stage: lint
script:
- npx tsc --noEmit
allow_failure: false
test:unit:
<<: *node_template
stage: test
script:
- npm test || echo "No test script found"
coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
artifacts:
when: always
reports:
junit: junit.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
paths:
- coverage/
expire_in: 1 week
build:app:
<<: *node_template
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
needs:
- lint:eslint
- lint:typecheck
- test:unit
test:e2e:
image: mcr.microsoft.com/playwright:v1.42.0-focal
stage: test
script:
- npm ci --cache .npm --prefer-offline
- npx playwright install chromium
- npm run test:e2e || echo "No E2E tests configured"
artifacts:
when: always
paths:
- playwright-report/
expire_in: 1 week
needs:
- build:app
allow_failure: true
security:audit:
<<: *node_template
stage: security
script:
- npm audit --audit-level=moderate || true
allow_failure: true
security:trivy:
stage: security
image:
name: aquasec/trivy:latest
entrypoint: ['']
script:
- trivy fs --exit-code 0 --no-progress --format json --output trivy-report.json .
- trivy fs --exit-code 1 --severity CRITICAL --no-progress .
artifacts:
reports:
container_scanning: trivy-report.json
allow_failure: true
docker:build:
stage: docker
image: docker:24-dind
services:
- docker:24-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $REGISTRY:$CI_COMMIT_REF_SLUG -t $REGISTRY:$CI_COMMIT_SHORT_SHA .
- docker push $REGISTRY:$CI_COMMIT_REF_SLUG
- docker push $REGISTRY:$CI_COMMIT_SHORT_SHA
- |
if [ "$CI_COMMIT_REF_NAME" = "main" ]; then
docker tag $REGISTRY:$CI_COMMIT_SHORT_SHA $REGISTRY:latest
docker push $REGISTRY:latest
fi
needs:
- build:app
- test:unit
- security:audit
only:
- main
- develop
- tags
deploy:staging:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache curl
script:
- echo "Deploying to staging environment..."
- echo "Image: $REGISTRY:develop-$CI_COMMIT_SHORT_SHA"
- |
curl -X POST $STAGING_WEBHOOK_URL \
-H "Content-Type: application/json" \
-d "{\"image\":\"$REGISTRY:develop\",\"sha\":\"$CI_COMMIT_SHORT_SHA\"}"
environment:
name: staging
url: https://staging.codeforge.example.com
needs:
- docker:build
only:
- develop
deploy:production:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache curl
script:
- echo "Deploying to production environment..."
- echo "Image: $REGISTRY:main-$CI_COMMIT_SHORT_SHA"
- |
curl -X POST $PRODUCTION_WEBHOOK_URL \
-H "Content-Type: application/json" \
-d "{\"image\":\"$REGISTRY:latest\",\"sha\":\"$CI_COMMIT_SHORT_SHA\"}"
environment:
name: production
url: https://codeforge.example.com
needs:
- docker:build
- test:e2e
when: manual
only:
- main

350
CI_CD_GUIDE.md Normal file
View File

@@ -0,0 +1,350 @@
# CI/CD Configuration Guide
This project includes comprehensive CI/CD configurations for multiple platforms. Choose the one that best fits your infrastructure.
## Table of Contents
- [GitHub Actions](#github-actions)
- [GitLab CI](#gitlab-ci)
- [Jenkins](#jenkins)
- [CircleCI](#circleci)
- [Docker Setup](#docker-setup)
---
## GitHub Actions
### Location
- `.github/workflows/ci.yml` - Main CI/CD pipeline
- `.github/workflows/release.yml` - Release automation
### Features
- ✅ Lint and type checking
- ✅ Unit and E2E tests
- ✅ Docker build and push to GHCR
- ✅ Security scanning with Trivy
- ✅ Automated deployments to staging/production
- ✅ Release creation with ZIP artifacts
### Setup
1. **Enable GitHub Actions** in your repository settings
2. **Configure secrets** (Settings → Secrets and variables → Actions):
```
CODECOV_TOKEN # Optional: for code coverage reporting
SLACK_WEBHOOK # Optional: for Slack notifications
STAGING_WEBHOOK_URL # Webhook for staging deployment
PRODUCTION_WEBHOOK_URL # Webhook for production deployment
```
3. **Enable GitHub Packages** for Docker image storage (automatically enabled)
4. **Branch Protection** (recommended):
- Require status checks to pass before merging
- Require pull request reviews
### Usage
- Push to `develop` → Runs tests and deploys to staging
- Push to `main` → Runs full pipeline and deploys to production
- Create tag `v*` → Triggers release workflow
---
## GitLab CI
### Location
- `.gitlab-ci.yml`
### Features
- ✅ Multi-stage pipeline with dependency caching
- ✅ Parallel test execution
- ✅ Docker build and push to GitLab Registry
- ✅ Security scanning and audit reports
- ✅ Manual approval for production deployments
### Setup
1. **Configure CI/CD variables** (Settings → CI/CD → Variables):
```
STAGING_WEBHOOK_URL # Webhook for staging deployment
PRODUCTION_WEBHOOK_URL # Webhook for production deployment
```
2. **Enable GitLab Container Registry** (enabled by default)
3. **Configure runners** with Docker executor:
```toml
[[runners]]
name = "docker-runner"
executor = "docker"
[runners.docker]
image = "node:20-alpine"
privileged = true
```
### Usage
- Pipeline runs automatically on push
- Jobs are cached for faster execution
- Production deployment requires manual approval
---
## Jenkins
### Location
- `Jenkinsfile`
### Features
- ✅ Declarative pipeline with parallel stages
- ✅ Integration with Slack for notifications
- ✅ Artifact archiving and HTML report publishing
- ✅ Manual approval for production deployments
- ✅ Automatic workspace cleanup
### Setup
1. **Install required plugins**:
- Pipeline
- NodeJS
- Docker Pipeline
- Slack Notification
- HTML Publisher
2. **Configure Node.js** (Manage Jenkins → Tools):
- Add Node.js installation named "Node 20"
- Version: 20.x
3. **Configure credentials**:
```
docker-registry-credentials # Username/password for GHCR
```
4. **Set environment variables** in Jenkins configuration:
```
GIT_REPO_OWNER
GIT_REPO_NAME
STAGING_WEBHOOK_URL
PRODUCTION_WEBHOOK_URL
SLACK_CHANNEL
```
5. **Create multibranch pipeline**:
- New Item → Multibranch Pipeline
- Add source: Git/GitHub
- Script Path: Jenkinsfile
### Usage
- Pipeline triggers on SCM changes (polling or webhooks)
- View results in Blue Ocean interface
- Approve production deployments manually
---
## CircleCI
### Location
- `.circleci/config.yml`
### Features
- ✅ Workflow orchestration with job dependencies
- ✅ Docker layer caching for faster builds
- ✅ Slack notifications via orb
- ✅ Test result and artifact storage
- ✅ Approval step for production deployments
### Setup
1. **Connect repository** to CircleCI
2. **Configure environment variables** (Project Settings → Environment Variables):
```
DOCKER_USERNAME # GitHub username
DOCKER_PASSWORD # GitHub personal access token
STAGING_WEBHOOK_URL # Webhook for staging deployment
PRODUCTION_WEBHOOK_URL # Webhook for production deployment
SLACK_ACCESS_TOKEN # Optional: for Slack notifications
SLACK_DEFAULT_CHANNEL # Optional: default Slack channel
```
3. **Enable Docker Layer Caching** (requires paid plan):
- Project Settings → Advanced → Enable Docker Layer Caching
### Usage
- Pipeline runs on every push
- Manual approval required for production on `main` branch
- View detailed insights in CircleCI dashboard
---
## Docker Setup
### Files
- `Dockerfile` - Multi-stage build for production
- `docker-compose.yml` - Local development and deployment
- `nginx.conf` - Nginx configuration for serving app
- `.dockerignore` - Excludes unnecessary files
### Build and Run Locally
```bash
# Build image
docker build -t codeforge:local .
# Run container
docker run -p 3000:80 codeforge:local
# Or use docker-compose
docker-compose up -d
```
### Production Deployment
The Docker image is automatically built and pushed to GHCR:
```bash
# Pull latest image
docker pull ghcr.io/<username>/<repo>:latest
# Run in production
docker run -d \
-p 80:80 \
--name codeforge \
--restart unless-stopped \
ghcr.io/<username>/<repo>:latest
```
### Health Checks
The container includes a health check endpoint at `/health`:
```bash
curl http://localhost:3000/health
# Response: healthy
```
---
## Common Configuration
### Environment Variables
All CI/CD platforms use these common environment variables:
| Variable | Description | Required |
|----------|-------------|----------|
| `NODE_VERSION` | Node.js version | Yes (default: 20) |
| `REGISTRY` | Docker registry URL | Yes (default: ghcr.io) |
| `IMAGE_NAME` | Docker image name | Yes |
| `STAGING_WEBHOOK_URL` | Staging deployment webhook | Optional |
| `PRODUCTION_WEBHOOK_URL` | Production deployment webhook | Optional |
| `CODECOV_TOKEN` | Codecov integration token | Optional |
| `SLACK_WEBHOOK` | Slack webhook URL | Optional |
### Branch Strategy
- `main` - Production branch, deploys to production
- `develop` - Development branch, deploys to staging
- `feature/*` - Feature branches, runs tests only
- `v*` tags - Triggers release creation
### Pipeline Stages
All pipelines follow a similar structure:
1. **Lint** - ESLint and TypeScript checks
2. **Test** - Unit tests with coverage
3. **Build** - Application build
4. **E2E** - Playwright end-to-end tests
5. **Security** - npm audit and Trivy scan
6. **Docker** - Build and push image
7. **Deploy** - Staging (auto) and Production (manual)
### Deployment Webhooks
Configure deployment webhooks to integrate with your hosting platform:
```bash
# Example webhook payload
{
"image": "ghcr.io/<username>/<repo>:latest",
"sha": "abc123",
"environment": "production"
}
```
Supported platforms:
- Vercel
- Netlify
- AWS ECS/EKS
- Kubernetes
- Custom deployment scripts
---
## Troubleshooting
### GitHub Actions
**Issue**: Docker push fails
```bash
Solution: Check GITHUB_TOKEN permissions in repository settings
Settings → Actions → General → Workflow permissions → Read and write
```
### GitLab CI
**Issue**: Runner fails to pull image
```bash
Solution: Check runner has access to Docker
docker info # Should work on runner
```
### Jenkins
**Issue**: Pipeline hangs on input step
```bash
Solution: Check Jenkins has sufficient executors
Manage Jenkins → Configure System → # of executors
```
### CircleCI
**Issue**: Build fails with out of memory
```bash
Solution: Increase resource class in config.yml
resource_class: large # or xlarge
```
---
## Additional Resources
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
- [GitLab CI/CD Documentation](https://docs.gitlab.com/ee/ci/)
- [Jenkins Pipeline Documentation](https://www.jenkins.io/doc/book/pipeline/)
- [CircleCI Documentation](https://circleci.com/docs/)
- [Docker Documentation](https://docs.docker.com/)
---
## Security Best Practices
1. **Never commit secrets** to the repository
2. **Use environment variables** for sensitive data
3. **Enable branch protection** on main/develop branches
4. **Require code reviews** before merging
5. **Run security scans** in every pipeline
6. **Keep dependencies updated** using Dependabot/Renovate
7. **Use signed commits** for production deployments
8. **Implement RBAC** for deployment approvals
---
## License
This CI/CD configuration is part of CodeForge and follows the same license as the main project.

24
Dockerfile Normal file
View File

@@ -0,0 +1,24 @@
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM nginx:alpine AS runtime
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/health || exit 1
CMD ["nginx", "-g", "daemon off;"]

291
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,291 @@
pipeline {
agent any
environment {
NODE_VERSION = '20'
REGISTRY = 'ghcr.io'
IMAGE_NAME = "${env.REGISTRY}/${env.GIT_REPO_OWNER}/${env.GIT_REPO_NAME}"
DOCKER_CREDENTIALS = credentials('docker-registry-credentials')
SLACK_CHANNEL = '#deployments'
}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
disableConcurrentBuilds()
timeout(time: 1, unit: 'HOURS')
timestamps()
}
triggers {
pollSCM('H/5 * * * *')
githubPush()
}
stages {
stage('Checkout') {
steps {
checkout scm
script {
env.GIT_COMMIT_SHORT = sh(
script: "git rev-parse --short HEAD",
returnStdout: true
).trim()
}
}
}
stage('Setup') {
steps {
script {
nodejs(nodeJSInstallationName: "Node ${NODE_VERSION}") {
sh '''
node --version
npm --version
npm ci
'''
}
}
}
}
stage('Lint') {
parallel {
stage('ESLint') {
steps {
script {
nodejs(nodeJSInstallationName: "Node ${NODE_VERSION}") {
sh 'npm run lint || echo "No lint script found"'
}
}
}
}
stage('TypeScript Check') {
steps {
script {
nodejs(nodeJSInstallationName: "Node ${NODE_VERSION}") {
sh 'npx tsc --noEmit'
}
}
}
}
}
}
stage('Test') {
steps {
script {
nodejs(nodeJSInstallationName: "Node ${NODE_VERSION}") {
sh 'npm test || echo "No test script found"'
}
}
}
post {
always {
junit testResults: '**/junit.xml', allowEmptyResults: true
publishHTML([
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'coverage',
reportFiles: 'index.html',
reportName: 'Coverage Report'
])
}
}
}
stage('Build') {
steps {
script {
nodejs(nodeJSInstallationName: "Node ${NODE_VERSION}") {
sh 'npm run build'
}
}
}
post {
success {
archiveArtifacts artifacts: 'dist/**/*', fingerprint: true
}
}
}
stage('E2E Tests') {
when {
anyOf {
branch 'main'
branch 'develop'
}
}
steps {
script {
nodejs(nodeJSInstallationName: "Node ${NODE_VERSION}") {
sh '''
npx playwright install --with-deps chromium
npm run test:e2e || echo "No E2E tests configured"
'''
}
}
}
post {
always {
publishHTML([
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'playwright-report',
reportFiles: 'index.html',
reportName: 'Playwright Report'
])
}
}
}
stage('Security Scan') {
parallel {
stage('NPM Audit') {
steps {
script {
nodejs(nodeJSInstallationName: "Node ${NODE_VERSION}") {
sh 'npm audit --audit-level=moderate || true'
}
}
}
}
stage('Trivy Scan') {
steps {
sh '''
docker run --rm -v $(pwd):/workspace aquasec/trivy:latest \
fs --exit-code 0 --no-progress --format json \
--output /workspace/trivy-report.json /workspace
'''
}
post {
always {
archiveArtifacts artifacts: 'trivy-report.json', allowEmptyArchive: true
}
}
}
}
}
stage('Docker Build') {
when {
anyOf {
branch 'main'
branch 'develop'
}
}
steps {
script {
def imageTags = [
"${IMAGE_NAME}:${env.BRANCH_NAME}",
"${IMAGE_NAME}:${env.BRANCH_NAME}-${env.GIT_COMMIT_SHORT}"
]
if (env.BRANCH_NAME == 'main') {
imageTags.add("${IMAGE_NAME}:latest")
}
docker.withRegistry("https://${REGISTRY}", 'docker-registry-credentials') {
def customImage = docker.build("${IMAGE_NAME}:${env.BUILD_ID}")
imageTags.each { tag ->
customImage.push(tag.split(':')[1])
}
}
}
}
}
stage('Deploy to Staging') {
when {
branch 'develop'
}
environment {
DEPLOY_ENV = 'staging'
}
steps {
script {
echo "Deploying to staging environment..."
echo "Image: ${IMAGE_NAME}:develop-${env.GIT_COMMIT_SHORT}"
sh '''
curl -X POST ${STAGING_WEBHOOK_URL} \
-H "Content-Type: application/json" \
-d "{\\"image\\":\\"${IMAGE_NAME}:develop\\",\\"sha\\":\\"${GIT_COMMIT_SHORT}\\"}"
'''
}
}
post {
success {
slackSend(
channel: SLACK_CHANNEL,
color: 'good',
message: "Staging deployment successful: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
)
}
failure {
slackSend(
channel: SLACK_CHANNEL,
color: 'danger',
message: "Staging deployment failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
)
}
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
environment {
DEPLOY_ENV = 'production'
}
steps {
input message: 'Deploy to production?', ok: 'Deploy'
script {
echo "Deploying to production environment..."
echo "Image: ${IMAGE_NAME}:latest"
sh '''
curl -X POST ${PRODUCTION_WEBHOOK_URL} \
-H "Content-Type: application/json" \
-d "{\\"image\\":\\"${IMAGE_NAME}:latest\\",\\"sha\\":\\"${GIT_COMMIT_SHORT}\\"}"
'''
}
}
post {
success {
slackSend(
channel: SLACK_CHANNEL,
color: 'good',
message: "Production deployment successful: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
)
}
failure {
slackSend(
channel: SLACK_CHANNEL,
color: 'danger',
message: "Production deployment failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
)
}
}
}
}
post {
always {
cleanWs()
}
success {
echo 'Pipeline completed successfully!'
}
failure {
echo 'Pipeline failed!'
slackSend(
channel: SLACK_CHANNEL,
color: 'danger',
message: "Build failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
)
}
}
}

View File

@@ -86,6 +86,7 @@ The application includes comprehensive built-in documentation:
- **Roadmap** - Completed features and planned enhancements
- **Agents Files** - AI service architecture and integration points
- **Sass Styles Guide** - Custom Material UI components, utilities, mixins, and animations
- **CI/CD Guide** - Complete setup guide for all CI/CD platforms
Access documentation by clicking the **Documentation** tab in the application.
@@ -105,16 +106,23 @@ Access documentation by clicking the **Documentation** tab in the application.
- ZIP file export with README generation
- Keyboard shortcuts for power users
### ✅ Recently Added (v4.2)
- Complete CI/CD configurations (GitHub Actions, GitLab CI, Jenkins, CircleCI)
- Docker containerization with multi-stage builds
- Nginx configuration for production deployment
- Automated release workflow with versioning
- Security scanning integration (Trivy, npm audit)
- Slack notification integration
- Health check endpoints
### 🔮 Planned
- Real-time preview with hot reload
- Database seeding designer
- API client generator
- Visual form builder
- Authentication designer (JWT, OAuth, sessions)
- Docker configuration generator
- GraphQL API designer
- State management designer (Redux, Zustand, Jotai)
- CI/CD pipeline generator
- Component library export
- Design system generator
- Collaboration features
@@ -138,6 +146,7 @@ The Spark Template files and resources from GitHub are licensed under the terms
- [Full Documentation](./PRD.md) - Complete product requirements and design decisions
- [Error Repair Guide](./ERROR_REPAIR_GUIDE.md) - Error detection and repair system documentation
- [CI/CD Guide](./CI_CD_GUIDE.md) - Complete CI/CD setup and configuration guide
---

26
docker-compose.yml Normal file
View File

@@ -0,0 +1,26 @@
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- '3000:80'
environment:
- NODE_ENV=production
restart: unless-stopped
healthcheck:
test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost/health']
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.codeforge.rule=Host(`codeforge.example.com`)'
- 'traefik.http.services.codeforge.loadbalancer.server.port=80'
networks:
default:
name: codeforge-network

28
nginx.conf Normal file
View File

@@ -0,0 +1,28 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
error_page 404 /index.html;
}

View File

@@ -25,7 +25,8 @@ import {
Rocket,
Target,
Lightbulb,
MagnifyingGlass
MagnifyingGlass,
GitBranch
} from '@phosphor-icons/react'
export function DocumentationView() {
@@ -54,6 +55,10 @@ export function DocumentationView() {
<PaintBrush size={18} />
Sass Styles Guide
</TabsTrigger>
<TabsTrigger value="cicd" className="gap-2">
<GitBranch size={18} />
CI/CD Guide
</TabsTrigger>
</TabsList>
</div>
<div className="relative">
@@ -433,6 +438,18 @@ export function DocumentationView() {
description="Next.js configuration, npm package management, and build script customization"
version="v4.0"
/>
<RoadmapItem
status="completed"
title="CI/CD Configuration"
description="Complete CI/CD pipelines for GitHub Actions, GitLab CI, Jenkins, and CircleCI"
version="v4.2"
/>
<RoadmapItem
status="completed"
title="Docker Containerization"
description="Multi-stage Docker builds with Nginx, docker-compose, and health checks"
version="v4.2"
/>
</div>
</div>
@@ -1127,6 +1144,450 @@ function MyComponent() {
</Card>
</div>
</TabsContent>
<TabsContent value="cicd" className="m-0 space-y-6">
<div className="space-y-4">
<div className="flex items-center gap-4">
<div className="w-16 h-16 rounded-xl bg-gradient-to-br from-primary to-accent flex items-center justify-center">
<GitBranch size={32} weight="duotone" className="text-white" />
</div>
<div>
<h1 className="text-4xl font-bold">CI/CD Guide</h1>
<p className="text-lg text-muted-foreground">
Complete deployment automation for multiple platforms
</p>
</div>
</div>
<Separator />
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Overview</h2>
<p className="text-foreground/90 leading-relaxed">
CodeForge includes production-ready CI/CD configurations for GitHub Actions, GitLab CI, Jenkins,
and CircleCI. Each pipeline includes linting, testing, security scanning, Docker image building,
and automated deployment workflows.
</p>
</div>
<Card>
<CardHeader>
<CardTitle>Available Configurations</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<CICDPlatformItem
name="GitHub Actions"
file=".github/workflows/ci.yml"
description="Complete CI/CD with GHCR Docker registry integration"
features={[
'Parallel lint and test execution',
'E2E tests with Playwright',
'Docker build and push to GitHub Container Registry',
'Security scanning with Trivy',
'Automated staging and production deployments',
'Release workflow with versioned artifacts'
]}
/>
<CICDPlatformItem
name="GitLab CI"
file=".gitlab-ci.yml"
description="Multi-stage pipeline with GitLab Container Registry"
features={[
'Dependency caching for faster builds',
'Coverage reporting with Cobertura',
'Docker-in-Docker builds',
'Manual production approval gates',
'Webhook-based deployment triggers'
]}
/>
<CICDPlatformItem
name="Jenkins"
file="Jenkinsfile"
description="Declarative pipeline with Slack notifications"
features={[
'Node.js environment configuration',
'HTML report publishing for tests and coverage',
'Artifact archiving and fingerprinting',
'Manual production deployment approval',
'Slack integration for deployment notifications'
]}
/>
<CICDPlatformItem
name="CircleCI"
file=".circleci/config.yml"
description="Workflow orchestration with orb integrations"
features={[
'Docker layer caching for optimization',
'Job dependency management',
'Test results and artifact storage',
'Approval workflows for production',
'Slack notifications via orb'
]}
/>
</CardContent>
</Card>
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Pipeline Stages</h2>
<p className="text-foreground/90 leading-relaxed">
All CI/CD configurations follow a similar multi-stage pipeline structure:
</p>
<div className="grid gap-3">
<PipelineStageCard
stage="Lint"
description="ESLint and TypeScript type checking to ensure code quality"
duration="~1-2 min"
/>
<PipelineStageCard
stage="Test"
description="Unit tests with coverage reporting and result artifacts"
duration="~2-3 min"
/>
<PipelineStageCard
stage="Build"
description="Production build with artifact generation for deployment"
duration="~2-4 min"
/>
<PipelineStageCard
stage="E2E Tests"
description="Playwright end-to-end tests with HTML reports"
duration="~3-5 min"
/>
<PipelineStageCard
stage="Security"
description="npm audit and Trivy vulnerability scanning"
duration="~1-2 min"
/>
<PipelineStageCard
stage="Docker Build"
description="Multi-stage Docker image build and push to registry"
duration="~3-5 min"
/>
<PipelineStageCard
stage="Deploy"
description="Automated deployment to staging and production environments"
duration="~1-3 min"
/>
</div>
</div>
<Card>
<CardHeader>
<CardTitle>Docker Configuration</CardTitle>
<CardDescription>Containerization for production deployment</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<h3 className="font-semibold">Files Included</h3>
<div className="space-y-2 ml-4">
<div className="space-y-1">
<code className="text-sm font-mono text-accent">Dockerfile</code>
<p className="text-sm text-muted-foreground">Multi-stage build with Node.js builder and Nginx runtime</p>
</div>
<div className="space-y-1">
<code className="text-sm font-mono text-accent">nginx.conf</code>
<p className="text-sm text-muted-foreground">Production Nginx configuration with health checks and caching</p>
</div>
<div className="space-y-1">
<code className="text-sm font-mono text-accent">docker-compose.yml</code>
<p className="text-sm text-muted-foreground">Local development and deployment orchestration</p>
</div>
<div className="space-y-1">
<code className="text-sm font-mono text-accent">.dockerignore</code>
<p className="text-sm text-muted-foreground">Optimized build context by excluding unnecessary files</p>
</div>
</div>
</div>
<Separator />
<div className="space-y-2">
<h3 className="font-semibold">Docker Commands</h3>
<pre className="custom-mui-code-block">
{`# Build image locally
docker build -t codeforge:local .
# Run container
docker run -p 3000:80 codeforge:local
# Use docker-compose
docker-compose up -d
# Pull from registry
docker pull ghcr.io/<username>/<repo>:latest`}
</pre>
</div>
<Separator />
<div className="space-y-2">
<h3 className="font-semibold">Features</h3>
<ul className="space-y-2 text-sm">
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Multi-stage build reduces final image size to ~50MB</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Nginx serves static files with gzip compression</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Health check endpoint at /health for orchestration</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Automatic cache headers for static assets</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>SPA routing support with fallback to index.html</span>
</li>
</ul>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Environment Variables</CardTitle>
<CardDescription>Required configuration for CI/CD platforms</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b">
<th className="text-left py-2 pr-4 font-semibold">Variable</th>
<th className="text-left py-2 pr-4 font-semibold">Description</th>
<th className="text-left py-2 font-semibold">Required</th>
</tr>
</thead>
<tbody className="text-muted-foreground">
<tr className="border-b">
<td className="py-2 pr-4"><code className="text-accent">NODE_VERSION</code></td>
<td className="py-2 pr-4">Node.js version (default: 20)</td>
<td className="py-2">No</td>
</tr>
<tr className="border-b">
<td className="py-2 pr-4"><code className="text-accent">REGISTRY</code></td>
<td className="py-2 pr-4">Docker registry URL (default: ghcr.io)</td>
<td className="py-2">No</td>
</tr>
<tr className="border-b">
<td className="py-2 pr-4"><code className="text-accent">STAGING_WEBHOOK_URL</code></td>
<td className="py-2 pr-4">Webhook for staging deployments</td>
<td className="py-2">Optional</td>
</tr>
<tr className="border-b">
<td className="py-2 pr-4"><code className="text-accent">PRODUCTION_WEBHOOK_URL</code></td>
<td className="py-2 pr-4">Webhook for production deployments</td>
<td className="py-2">Optional</td>
</tr>
<tr className="border-b">
<td className="py-2 pr-4"><code className="text-accent">CODECOV_TOKEN</code></td>
<td className="py-2 pr-4">Codecov integration token</td>
<td className="py-2">Optional</td>
</tr>
<tr className="border-b">
<td className="py-2 pr-4"><code className="text-accent">SLACK_WEBHOOK</code></td>
<td className="py-2 pr-4">Slack webhook for notifications</td>
<td className="py-2">Optional</td>
</tr>
</tbody>
</table>
</div>
</div>
</CardContent>
</Card>
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Branch Strategy</h2>
<div className="grid gap-4">
<Card className="bg-green-500/5 border-green-500/20">
<CardContent className="pt-4 pb-4">
<div className="flex items-start gap-3">
<GitBranch size={20} weight="duotone" className="text-green-500 mt-0.5" />
<div className="space-y-1">
<h4 className="font-semibold">main</h4>
<p className="text-sm text-muted-foreground">
Production branch - deploys to production environment (manual approval required)
</p>
</div>
</div>
</CardContent>
</Card>
<Card className="bg-blue-500/5 border-blue-500/20">
<CardContent className="pt-4 pb-4">
<div className="flex items-start gap-3">
<GitBranch size={20} weight="duotone" className="text-blue-500 mt-0.5" />
<div className="space-y-1">
<h4 className="font-semibold">develop</h4>
<p className="text-sm text-muted-foreground">
Development branch - automatically deploys to staging environment
</p>
</div>
</div>
</CardContent>
</Card>
<Card className="bg-purple-500/5 border-purple-500/20">
<CardContent className="pt-4 pb-4">
<div className="flex items-start gap-3">
<GitBranch size={20} weight="duotone" className="text-purple-500 mt-0.5" />
<div className="space-y-1">
<h4 className="font-semibold">feature/*</h4>
<p className="text-sm text-muted-foreground">
Feature branches - runs tests only, no deployment
</p>
</div>
</div>
</CardContent>
</Card>
<Card className="bg-orange-500/5 border-orange-500/20">
<CardContent className="pt-4 pb-4">
<div className="flex items-start gap-3">
<GitBranch size={20} weight="duotone" className="text-orange-500 mt-0.5" />
<div className="space-y-1">
<h4 className="font-semibold">v* tags</h4>
<p className="text-sm text-muted-foreground">
Version tags - triggers release workflow with artifacts and changelog
</p>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
<Card className="bg-accent/10 border-accent/20">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Lightbulb size={20} weight="duotone" className="text-accent" />
Quick Start
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-3">
<div className="space-y-2">
<h3 className="font-semibold flex items-center gap-2">
<span className="w-6 h-6 rounded-full bg-accent text-accent-foreground flex items-center justify-center text-sm">1</span>
Choose Your Platform
</h3>
<p className="text-sm text-foreground/80 ml-8">
Select GitHub Actions, GitLab CI, Jenkins, or CircleCI based on your infrastructure
</p>
</div>
<div className="space-y-2">
<h3 className="font-semibold flex items-center gap-2">
<span className="w-6 h-6 rounded-full bg-accent text-accent-foreground flex items-center justify-center text-sm">2</span>
Configure Secrets
</h3>
<p className="text-sm text-foreground/80 ml-8">
Add required environment variables and secrets in your platform's settings
</p>
</div>
<div className="space-y-2">
<h3 className="font-semibold flex items-center gap-2">
<span className="w-6 h-6 rounded-full bg-accent text-accent-foreground flex items-center justify-center text-sm">3</span>
Push to Repository
</h3>
<p className="text-sm text-foreground/80 ml-8">
Push code to main or develop branch to trigger the CI/CD pipeline
</p>
</div>
<div className="space-y-2">
<h3 className="font-semibold flex items-center gap-2">
<span className="w-6 h-6 rounded-full bg-accent text-accent-foreground flex items-center justify-center text-sm">4</span>
Monitor Pipeline
</h3>
<p className="text-sm text-foreground/80 ml-8">
View pipeline status, test results, and deployment logs in your platform's dashboard
</p>
</div>
</div>
</CardContent>
</Card>
<Card className="bg-muted/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Rocket size={20} weight="duotone" />
Best Practices
</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm">
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Never commit secrets - use environment variables and platform secret management</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Enable branch protection on main and develop branches</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Require code reviews and passing tests before merging</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Use manual approval gates for production deployments</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Monitor security scan results and fix vulnerabilities promptly</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Keep dependencies updated with Dependabot or Renovate</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Use semantic versioning for releases (v1.0.0, v1.1.0, etc.)</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>Configure Slack or email notifications for deployment status</span>
</li>
</ul>
</CardContent>
</Card>
<Card className="border-primary/30">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Package size={20} weight="duotone" />
Additional Resources
</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm">
<li className="flex items-start gap-2">
<FileCode size={16} className="text-accent mt-1 flex-shrink-0" />
<span><code className="text-accent">CI_CD_GUIDE.md</code> - Detailed setup guide for all platforms</span>
</li>
<li className="flex items-start gap-2">
<FileCode size={16} className="text-accent mt-1 flex-shrink-0" />
<span><code className="text-accent">.github/workflows/</code> - GitHub Actions workflows</span>
</li>
<li className="flex items-start gap-2">
<FileCode size={16} className="text-accent mt-1 flex-shrink-0" />
<span><code className="text-accent">.gitlab-ci.yml</code> - GitLab CI configuration</span>
</li>
<li className="flex items-start gap-2">
<FileCode size={16} className="text-accent mt-1 flex-shrink-0" />
<span><code className="text-accent">Jenkinsfile</code> - Jenkins pipeline definition</span>
</li>
<li className="flex items-start gap-2">
<FileCode size={16} className="text-accent mt-1 flex-shrink-0" />
<span><code className="text-accent">.circleci/config.yml</code> - CircleCI configuration</span>
</li>
</ul>
</CardContent>
</Card>
</div>
</TabsContent>
</div>
</ScrollArea>
</Tabs>
@@ -1134,6 +1595,59 @@ function MyComponent() {
)
}
function CICDPlatformItem({ name, file, description, features }: {
name: string
file: string
description: string
features: string[]
}) {
return (
<div className="space-y-3 border-l-2 border-accent pl-4">
<div className="space-y-1">
<div className="flex items-center gap-2">
<GitBranch size={18} className="text-accent" />
<h3 className="text-base font-semibold">{name}</h3>
</div>
<code className="text-xs text-muted-foreground font-mono">{file}</code>
<p className="text-sm text-foreground/90">{description}</p>
</div>
<div className="space-y-1">
<p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">Key Features:</p>
<ul className="space-y-1">
{features.map((feature, idx) => (
<li key={idx} className="text-sm text-foreground/80 flex items-start gap-2">
<CheckCircle size={14} weight="fill" className="text-accent mt-1 flex-shrink-0" />
<span>{feature}</span>
</li>
))}
</ul>
</div>
</div>
)
}
function PipelineStageCard({ stage, description, duration }: {
stage: string
description: string
duration: string
}) {
return (
<Card className="bg-primary/5 border-primary/20">
<CardContent className="pt-4 pb-4">
<div className="flex items-start justify-between gap-4">
<div className="space-y-1 flex-1">
<h4 className="font-semibold text-sm">{stage}</h4>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
<Badge variant="secondary" className="text-xs whitespace-nowrap">
{duration}
</Badge>
</div>
</CardContent>
</Card>
)
}
function SassComponentItem({ name, classes, description }: { name: string; classes: string[]; description: string }) {
return (
<div className="space-y-2 p-4 border rounded-lg bg-card">