fix: TypeScript build error and add Gitea CI/CD workflows
Deploy / build-and-push (push) Has been cancelled
Deploy / deploy-staging (push) Has been cancelled
Deploy / deploy-production (push) Has been cancelled
Test and Build / backend-test (push) Has been cancelled
Test and Build / frontend-test (push) Has been cancelled
Test and Build / docker-build (push) Has been cancelled
Test and Build / test-summary (push) Has been cancelled
Deploy / build-and-push (push) Has been cancelled
Deploy / deploy-staging (push) Has been cancelled
Deploy / deploy-production (push) Has been cancelled
Test and Build / backend-test (push) Has been cancelled
Test and Build / frontend-test (push) Has been cancelled
Test and Build / docker-build (push) Has been cancelled
Test and Build / test-summary (push) Has been cancelled
- Fix TypeScript type mismatch in CreateBucketDialog component - Make form fields optional to match yup schema validation - Add comprehensive Gitea Actions workflows for testing and deployment - Set up parallel testing for backend and frontend - Configure Docker build verification in CI pipeline - Add deployment workflow with staging and production environments 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,147 @@
|
|||||||
|
name: Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
tags: [ 'v*' ]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
environment:
|
||||||
|
description: 'Deployment environment'
|
||||||
|
required: true
|
||||||
|
default: 'staging'
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- staging
|
||||||
|
- production
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: gitea.nothaft.cloud
|
||||||
|
IMAGE_NAME: ${{ gitea.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
backend-image: ${{ steps.meta-backend.outputs.tags }}
|
||||||
|
frontend-image: ${{ steps.meta-frontend.outputs.tags }}
|
||||||
|
version: ${{ steps.meta-backend.outputs.version }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ gitea.actor }}
|
||||||
|
password: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
# Backend Image
|
||||||
|
- name: Extract backend metadata
|
||||||
|
id: meta-backend
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-backend
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=sha,prefix={{branch}}-
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Build and push backend image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: ./backend
|
||||||
|
file: ./docker/Dockerfile.backend
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta-backend.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta-backend.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
build-args: |
|
||||||
|
BUILD_DATE=${{ fromJSON(steps.meta-backend.outputs.json).labels['org.opencontainers.image.created'] }}
|
||||||
|
VERSION=${{ fromJSON(steps.meta-backend.outputs.json).labels['org.opencontainers.image.version'] }}
|
||||||
|
|
||||||
|
# Frontend Image
|
||||||
|
- name: Extract frontend metadata
|
||||||
|
id: meta-frontend
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=sha,prefix={{branch}}-
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Build and push frontend image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: ./frontend
|
||||||
|
file: ./docker/Dockerfile.frontend
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta-frontend.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta-frontend.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
build-args: |
|
||||||
|
BUILD_DATE=${{ fromJSON(steps.meta-frontend.outputs.json).labels['org.opencontainers.image.created'] }}
|
||||||
|
VERSION=${{ fromJSON(steps.meta-frontend.outputs.json).labels['org.opencontainers.image.version'] }}
|
||||||
|
|
||||||
|
deploy-staging:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build-and-push
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.event.inputs.environment == 'staging'
|
||||||
|
environment: staging
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Deploy to Staging
|
||||||
|
run: |
|
||||||
|
echo "Deploying to staging environment"
|
||||||
|
echo "Backend image: ${{ needs.build-and-push.outputs.backend-image }}"
|
||||||
|
echo "Frontend image: ${{ needs.build-and-push.outputs.frontend-image }}"
|
||||||
|
|
||||||
|
# Add your deployment commands here
|
||||||
|
# For example, using SSH to update docker-compose on staging server:
|
||||||
|
# ssh ${{ secrets.STAGING_HOST }} "cd /opt/minio-webui && docker compose pull && docker compose up -d"
|
||||||
|
|
||||||
|
deploy-production:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build-and-push
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v') || github.event.inputs.environment == 'production'
|
||||||
|
environment: production
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Deploy to Production
|
||||||
|
run: |
|
||||||
|
echo "Deploying to production environment"
|
||||||
|
echo "Backend image: ${{ needs.build-and-push.outputs.backend-image }}"
|
||||||
|
echo "Frontend image: ${{ needs.build-and-push.outputs.frontend-image }}"
|
||||||
|
echo "Version: ${{ needs.build-and-push.outputs.version }}"
|
||||||
|
|
||||||
|
# Add your production deployment commands here
|
||||||
|
# For example:
|
||||||
|
# ssh ${{ secrets.PROD_HOST }} "cd /opt/minio-webui && ./scripts/deploy.sh update"
|
||||||
|
|
||||||
|
- name: Create Release Notes
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
generate_release_notes: true
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
name: Test and Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_VERSION: '20'
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Backend Tests
|
||||||
|
backend-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./backend
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: backend/package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run linting
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: npm test
|
||||||
|
env:
|
||||||
|
NODE_ENV: test
|
||||||
|
JWT_SECRET: test-secret-key
|
||||||
|
ADMIN_PASSWORD_HASH: $2b$12$test
|
||||||
|
|
||||||
|
- name: Upload coverage
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: backend-coverage
|
||||||
|
path: backend/coverage
|
||||||
|
|
||||||
|
- name: Security audit
|
||||||
|
run: npm audit --audit-level=high
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
# Frontend Tests
|
||||||
|
frontend-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./frontend
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: frontend/package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci --legacy-peer-deps
|
||||||
|
|
||||||
|
- name: Run linting
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: npm test -- --watchAll=false --passWithNoTests
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
|
||||||
|
- name: Build application
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: frontend-build
|
||||||
|
path: frontend/build
|
||||||
|
|
||||||
|
- name: Security audit
|
||||||
|
run: npm audit --audit-level=high
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
# Docker Build Test
|
||||||
|
docker-build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [backend-test, frontend-test]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build Backend Docker Image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: ./backend
|
||||||
|
file: ./docker/Dockerfile.backend
|
||||||
|
push: false
|
||||||
|
tags: minio-webui-backend:test
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Build Frontend Docker Image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: ./frontend
|
||||||
|
file: ./docker/Dockerfile.frontend
|
||||||
|
push: false
|
||||||
|
tags: minio-webui-frontend:test
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Test Docker Compose
|
||||||
|
run: |
|
||||||
|
# Create test .env file
|
||||||
|
cat > .env << EOF
|
||||||
|
NODE_ENV=test
|
||||||
|
PORT=3000
|
||||||
|
LOG_LEVEL=info
|
||||||
|
ADMIN_PASSWORD_HASH=\$2b\$12\$test
|
||||||
|
JWT_SECRET=test-secret-key
|
||||||
|
SESSION_TIMEOUT=1800
|
||||||
|
ENABLE_IP_RESTRICTION=false
|
||||||
|
DEFAULT_MINIO_ALIAS=testminio
|
||||||
|
MINIO_ENDPOINT=http://minio:9000
|
||||||
|
MINIO_ACCESS_KEY=minioadmin
|
||||||
|
MINIO_SECRET_KEY=minioadmin
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Start services
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Wait for services to be healthy
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
# Check if services are running
|
||||||
|
docker compose ps
|
||||||
|
|
||||||
|
# Test backend health endpoint
|
||||||
|
curl -f http://localhost:3000/health || exit 1
|
||||||
|
|
||||||
|
# Test frontend
|
||||||
|
curl -f http://localhost/health || exit 1
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
docker compose down -v
|
||||||
|
|
||||||
|
# Summary job for branch protection
|
||||||
|
test-summary:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [backend-test, frontend-test, docker-build]
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Test Summary
|
||||||
|
run: |
|
||||||
|
echo "## Test Summary"
|
||||||
|
echo "Backend Tests: ${{ needs.backend-test.result }}"
|
||||||
|
echo "Frontend Tests: ${{ needs.frontend-test.result }}"
|
||||||
|
echo "Docker Build: ${{ needs.docker-build.result }}"
|
||||||
|
|
||||||
|
if [ "${{ needs.backend-test.result }}" != "success" ] || \
|
||||||
|
[ "${{ needs.frontend-test.result }}" != "success" ] || \
|
||||||
|
[ "${{ needs.docker-build.result }}" != "success" ]; then
|
||||||
|
echo "::error::One or more tests failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "All tests passed successfully!"
|
||||||
@@ -35,9 +35,9 @@ interface CreateBucketDialogProps {
|
|||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
bucketName: string;
|
bucketName: string;
|
||||||
createUser: boolean;
|
createUser?: boolean;
|
||||||
username: string;
|
username?: string;
|
||||||
password: string;
|
password?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const schema = yup.object({
|
const schema = yup.object({
|
||||||
@@ -50,7 +50,7 @@ const schema = yup.object({
|
|||||||
)
|
)
|
||||||
.min(3, 'Minimum 3 characters')
|
.min(3, 'Minimum 3 characters')
|
||||||
.max(63, 'Maximum 63 characters'),
|
.max(63, 'Maximum 63 characters'),
|
||||||
createUser: yup.boolean(),
|
createUser: yup.boolean().default(true),
|
||||||
username: yup
|
username: yup
|
||||||
.string()
|
.string()
|
||||||
.when('createUser', {
|
.when('createUser', {
|
||||||
@@ -119,12 +119,12 @@ const CreateBucketDialog: React.FC<CreateBucketDialogProps> = ({
|
|||||||
// Create bucket with user (like the script)
|
// Create bucket with user (like the script)
|
||||||
await api.post('/buckets/with-user', {
|
await api.post('/buckets/with-user', {
|
||||||
bucketName: data.bucketName,
|
bucketName: data.bucketName,
|
||||||
username: data.username,
|
username: data.username!,
|
||||||
password: data.password,
|
password: data.password!,
|
||||||
});
|
});
|
||||||
setCredentials({
|
setCredentials({
|
||||||
username: data.username,
|
username: data.username!,
|
||||||
password: data.password,
|
password: data.password!,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Create bucket only
|
// Create bucket only
|
||||||
|
|||||||
Reference in New Issue
Block a user