mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 02:51:34 +00:00
feat: Restructure workflows following Single Responsibility Principle
- Remove old monolithic workflows (ci.yml, ci-cd.yml, cd.yml) - Add focused workflows: lint.yml, test.yml, build.yml, security.yml, docker-build.yml, deploy.yml - Each workflow has a single, clear responsibility - Follow 2025 best practices with semantic versioning, OIDC auth, build attestations - Add comprehensive README.md with workflow documentation - Configure Dependabot for automated dependency updates Workflows now run independently and can be triggered separately for better CI/CD control.
This commit is contained in:
parent
afaf952a1a
commit
e428d18b0d
761
.github/workflows/README.md
vendored
Normal file
761
.github/workflows/README.md
vendored
Normal file
@ -0,0 +1,761 @@
|
||||
# GitHub Actions CI/CD Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the GitHub Actions CI/CD pipeline for the Tercul backend
|
||||
project, updated to 2025 best practices. The pipeline ensures code quality,
|
||||
security, and reliable deployments through automated testing, linting, security
|
||||
scanning, and containerized deployments.
|
||||
|
||||
### Quick Reference
|
||||
|
||||
| Workflow | File | Purpose | Triggers |
|
||||
|----------|------|---------|----------|
|
||||
| **Lint** | `lint.yml` | Code quality & style | Push/PR to main, develop |
|
||||
| **Test** | `test.yml` | Unit tests & compatibility | Push/PR to main, develop |
|
||||
| **Build** | `build.yml` | Binary compilation | Push/PR to main, develop |
|
||||
| **Security** | `security.yml` | CodeQL scanning | Push/PR to main + Weekly |
|
||||
| **Docker Build** | `docker-build.yml` | Container images | Push to main, Tags, PRs |
|
||||
| **Deploy** | `deploy.yml` | Production deployment | Tags (v*), Manual |
|
||||
|
||||
## Architecture
|
||||
|
||||
The CI/CD pipeline follows the **Single Responsibility Principle** with focused workflows:
|
||||
|
||||
1. **Lint** (`lint.yml`) - Code quality and style enforcement
|
||||
2. **Test** (`test.yml`) - Unit tests and compatibility matrix
|
||||
3. **Build** (`build.yml`) - Binary compilation and verification
|
||||
4. **Security** (`security.yml`) - CodeQL security scanning
|
||||
5. **Docker Build** (`docker-build.yml`) - Container image building and publishing
|
||||
6. **Deploy** (`deploy.yml`) - Production deployment orchestration
|
||||
|
||||
## Workflows
|
||||
|
||||
### Lint Workflow (`lint.yml`)
|
||||
|
||||
**Purpose**: Ensures code quality and consistent style across the codebase.
|
||||
|
||||
**Triggers**:
|
||||
|
||||
- Push to `main` and `develop` branches
|
||||
- Pull requests targeting `main` and `develop` branches
|
||||
|
||||
**Jobs**:
|
||||
|
||||
- `golangci-lint`: Go linting with golangci-lint
|
||||
- Checkout code
|
||||
- Setup Go 1.25 with caching
|
||||
- Install dependencies
|
||||
- Tidy modules (ensures go.mod/go.sum are clean)
|
||||
- Run linter with 5-minute timeout
|
||||
|
||||
**Configuration**:
|
||||
|
||||
- **Timeout**: 5 minutes
|
||||
- **Target**: All Go files (`./...`)
|
||||
- **Cache**: Enabled for faster runs
|
||||
|
||||
### Test Workflow (`test.yml`)
|
||||
|
||||
**Purpose**: Validates code functionality through comprehensive testing.
|
||||
|
||||
**Triggers**:
|
||||
|
||||
- Push to `main` and `develop` branches
|
||||
- Pull requests targeting `main` and `develop` branches
|
||||
|
||||
**Jobs**:
|
||||
|
||||
#### Unit Tests
|
||||
|
||||
- **Environment**: Ubuntu with PostgreSQL 15 and Redis 7
|
||||
- **Features**:
|
||||
|
||||
- Race detection enabled
|
||||
- Code coverage reporting (atomic mode)
|
||||
- HTML coverage report generation
|
||||
- Test result summaries in GitHub UI
|
||||
- 30-day artifact retention
|
||||
|
||||
**Services**:
|
||||
|
||||
- PostgreSQL 15 with health checks
|
||||
- Redis 7-alpine with health checks
|
||||
|
||||
#### Compatibility Matrix
|
||||
|
||||
- **Trigger**: Push to `main` branch only
|
||||
- **Strategy**: Tests across Go versions 1.22, 1.23, 1.24, 1.25
|
||||
- **Purpose**: Ensures compatibility with multiple Go versions
|
||||
- **Fail-fast**: Disabled (all versions tested even if one fails)
|
||||
|
||||
### Build Workflow (`build.yml`)
|
||||
|
||||
**Purpose**: Compiles the application binary and validates the build.
|
||||
|
||||
**Triggers**:
|
||||
|
||||
- Push to `main` and `develop` branches
|
||||
- Pull requests targeting `main` and `develop` branches
|
||||
|
||||
**Jobs**:
|
||||
|
||||
- `build-binary`: Binary compilation and verification
|
||||
- Dependency verification with `go mod verify`
|
||||
- Build to `bin/tercul-backend`
|
||||
- Binary validation test
|
||||
- Artifact upload (30-day retention)
|
||||
|
||||
**Permissions**:
|
||||
|
||||
- `contents: read` - Read repository code
|
||||
- `attestations: write` - Future SLSA attestation support
|
||||
- `id-token: write` - OIDC token for attestations
|
||||
|
||||
### Security Workflow (`security.yml`)
|
||||
|
||||
**Purpose**: Automated security vulnerability detection with CodeQL.
|
||||
|
||||
**Triggers**:
|
||||
|
||||
- Push to `main` branch
|
||||
- Pull requests targeting `main` branch
|
||||
- Scheduled: Every Monday at 14:20 UTC
|
||||
|
||||
**Jobs**:
|
||||
|
||||
- `codeql-analysis`: CodeQL security scanning for Go
|
||||
- Initialize CodeQL with Go language support
|
||||
- Build code for analysis
|
||||
- Perform security scan
|
||||
- Category: "backend-security" for tracking
|
||||
|
||||
**CodeQL Configuration**:
|
||||
|
||||
The workflow can be customized with additional query suites:
|
||||
|
||||
```yaml
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: go
|
||||
# Run security-extended suite for more comprehensive scanning
|
||||
queries: security-extended
|
||||
# Or use security-and-quality for maintainability checks
|
||||
# queries: security-and-quality
|
||||
```
|
||||
|
||||
**Available Query Suites**:
|
||||
|
||||
- `security-extended`: Default queries plus lower severity/precision queries
|
||||
- `security-and-quality`: Security queries plus maintainability and reliability
|
||||
|
||||
**Custom Query Packs**:
|
||||
|
||||
Add custom CodeQL query packs for specialized analysis:
|
||||
|
||||
```yaml
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: go
|
||||
packs: my-org/go-security-queries@1.0.0
|
||||
```
|
||||
|
||||
### Docker Build Workflow (`docker-build.yml`)
|
||||
|
||||
**Purpose**: Builds and publishes multi-architecture Docker images.
|
||||
|
||||
**Triggers**:
|
||||
|
||||
- Push to `main` branch
|
||||
- Tag pushes with `v*` pattern
|
||||
- Pull requests targeting `main` branch
|
||||
|
||||
**Jobs**:
|
||||
|
||||
- `build-image`: Multi-platform Docker image building
|
||||
|
||||
- Docker Buildx setup for multi-arch builds
|
||||
- Login to GitHub Container Registry
|
||||
- Metadata extraction for tags and labels
|
||||
- Build for AMD64 and ARM64 architectures
|
||||
- Push to registry (except for PRs)
|
||||
- Generate build provenance attestation
|
||||
|
||||
**Image Tagging Strategy**:
|
||||
|
||||
- `main` branch pushes → `main` + `sha-<hash>` tags
|
||||
- Tag pushes (`v1.2.3`) → `v1.2.3`, `1.2.3`, `1.2`, `sha-<hash>` tags
|
||||
- Pull requests → `pr-<number>` tag (build only, not pushed)
|
||||
|
||||
**Push Behavior**:
|
||||
|
||||
- **Pushes to main/tags**: Build and push to registry
|
||||
- **Pull requests**: Build only (validation, no push)
|
||||
|
||||
**Platforms**: linux/amd64, linux/arm64
|
||||
|
||||
### Deploy Workflow (`deploy.yml`)
|
||||
|
||||
**Purpose**: Production deployment orchestration to Docker Swarm.
|
||||
|
||||
**Triggers**:
|
||||
|
||||
- Tag pushes with `v*` pattern
|
||||
- Manual dispatch with version input
|
||||
|
||||
**Jobs**:
|
||||
|
||||
- `deploy-production`: Deployment to production environment
|
||||
|
||||
- Version extraction from tag or manual input
|
||||
- Docker Swarm service update (SSH-based deployment template)
|
||||
- Deployment summary with timestamp
|
||||
- Environment protection and tracking
|
||||
|
||||
**Environment**:
|
||||
|
||||
- Name: `production`
|
||||
- URL: Configurable production URL
|
||||
- Protection: Supports required reviewers and wait timers
|
||||
|
||||
**Manual Deployment**:
|
||||
|
||||
Deployments can be triggered manually from the Actions tab with a specific version.
|
||||
|
||||
**Required Secrets**:
|
||||
|
||||
- `SWARM_HOST`: Docker Swarm manager hostname/IP
|
||||
- `SWARM_SSH_KEY`: SSH private key for Swarm access
|
||||
|
||||
## Workflow Execution Order
|
||||
|
||||
**On Pull Request**:
|
||||
|
||||
1. Lint → Validates code style
|
||||
2. Test → Runs unit tests with coverage
|
||||
3. Build → Compiles binary
|
||||
4. Security → CodeQL analysis (main branch PRs only)
|
||||
5. Docker Build → Builds image (no push)
|
||||
|
||||
**On Push to main**:
|
||||
|
||||
1. Lint → Code quality check
|
||||
2. Test → Unit tests + compatibility matrix
|
||||
3. Build → Binary compilation
|
||||
4. Security → CodeQL scan
|
||||
5. Docker Build → Build and push image
|
||||
|
||||
**On Tag Push (v\*)**:
|
||||
|
||||
1. Docker Build → Build and push versioned image
|
||||
2. Deploy → Deploy to production
|
||||
|
||||
## Security Features
|
||||
|
||||
### Permissions Management
|
||||
|
||||
- **Principle of Least Privilege**: Each workflow has minimal required permissions
|
||||
- **GITHUB_TOKEN Restrictions**: Read-only by default, elevated only when necessary
|
||||
- **Workflow Separation**: Each workflow operates independently
|
||||
- **Attestation Permissions**: For build provenance and SLSA compliance
|
||||
|
||||
### Code Security
|
||||
|
||||
- **CodeQL Integration**: Automated security scanning for Go code
|
||||
- **Dependency Verification**: `go mod verify` ensures integrity
|
||||
- **Module Tidying**: `go mod tidy` prevents dependency drift
|
||||
|
||||
### Container Security
|
||||
|
||||
- **Multi-platform Builds**: Ensures compatibility and security across architectures
|
||||
- **Provenance Attestation**: Cryptographic proof of build integrity
|
||||
- **Registry Security**: GitHub Container Registry with token-based authentication
|
||||
|
||||
### Secrets Management
|
||||
|
||||
- **No Hardcoded Secrets**: All sensitive data uses GitHub secrets
|
||||
- **Environment Variables**: Proper isolation of configuration
|
||||
- **GITHUB_TOKEN**: Automatic authentication for package registries
|
||||
- **Granular Permissions**: Package-level access control
|
||||
|
||||
### Package Registry Security
|
||||
|
||||
- **GITHUB_TOKEN Authentication**: No personal access tokens required
|
||||
- **Automatic Permissions**: Packages inherit repository visibility
|
||||
- **Repository Scoped**: Packages linked to source repository
|
||||
- **Granular Access**: Fine-grained permissions per package
|
||||
- **Artifact Attestation**: Cryptographic proof of build provenance
|
||||
- **OIDC Support**: Token-based authentication without long-lived credentials
|
||||
|
||||
## Best Practices Implemented
|
||||
|
||||
### 2025 Updates
|
||||
|
||||
- **Semantic Versioning**: Actions pinned to major versions (e.g., `@v5`) instead of SHA
|
||||
- **Caching Optimization**: Go module and Docker layer caching
|
||||
- **Matrix Testing**: Cross-version compatibility validation
|
||||
- **Service Health Checks**: Database and Redis readiness verification
|
||||
- **Artifact Management**: Proper retention policies and naming
|
||||
|
||||
### Performance Optimizations
|
||||
|
||||
- **Dependency Caching**: Reduces setup time significantly
|
||||
- **Parallel Jobs**: Independent jobs run concurrently
|
||||
- **Conditional Execution**: Security scans only on main branch
|
||||
- **Artifact Upload**: Efficient storage and retrieval
|
||||
|
||||
### Reliability Features
|
||||
|
||||
- **Timeout Configuration**: Prevents hanging jobs
|
||||
- **Error Handling**: Proper exit codes and logging
|
||||
- **Health Checks**: Service readiness validation
|
||||
- **Retention Policies**: Balanced storage management
|
||||
|
||||
## Configuration Details
|
||||
|
||||
### Go Version
|
||||
|
||||
- Primary: Go 1.25
|
||||
- Matrix: Go 1.22, 1.23, 1.24, 1.25
|
||||
|
||||
### Services
|
||||
|
||||
- **PostgreSQL**: Version 15 with health checks
|
||||
- **Redis**: Version 7-alpine with ping health checks
|
||||
|
||||
### Tools
|
||||
|
||||
- **Linter**: golangci-lint latest with 5-minute timeout
|
||||
- **Testing**: `go test` with race detection and coverage
|
||||
- **Building**: `go build` with verbose output
|
||||
- **Security**: CodeQL for Go analysis
|
||||
|
||||
### Caching
|
||||
|
||||
- **Go Modules**: Automatic caching via setup-go action
|
||||
- **Docker Layers**: GitHub Actions cache with GHA type
|
||||
- **CodeQL Databases**: Stored in `${{ github.runner_temp }}/codeql_databases`
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Dependabot Configuration
|
||||
|
||||
- **GitHub Actions**: Weekly updates with "ci" prefix
|
||||
- **Go Modules**: Weekly updates with "deps" prefix
|
||||
- **Automated PRs**: Keeps dependencies current and secure
|
||||
|
||||
### Monitoring
|
||||
|
||||
- **Workflow Runs**: GitHub Actions tab for execution monitoring
|
||||
- **Security Alerts**: Code scanning results and dependency alerts
|
||||
- **Coverage Reports**: Artifact downloads for test coverage analysis
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Common Issues
|
||||
|
||||
1. **Cache Misses**: Clear caches if corruption suspected
|
||||
2. **Service Failures**: Check health check configurations
|
||||
3. **Permission Errors**: Verify GITHUB_TOKEN scopes
|
||||
4. **Timeout Issues**: Adjust timeout values in workflow configurations
|
||||
5. **Docker Push Failures**: Check package write permissions
|
||||
6. **Registry Authentication**: Ensure `packages: write` permission is set
|
||||
|
||||
#### Package Registry Issues
|
||||
|
||||
**Problem**: Cannot push to GitHub Container Registry
|
||||
|
||||
```yaml
|
||||
# Solution: Ensure proper permissions
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
```
|
||||
|
||||
**Problem**: Package not visible after push
|
||||
|
||||
- Check package visibility settings (public/private/internal)
|
||||
- Verify repository is linked to package
|
||||
- Ensure workflow completed successfully
|
||||
|
||||
**Problem**: Cannot pull package in workflow
|
||||
|
||||
```yaml
|
||||
# Solution: Login to registry first
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
#### Debugging
|
||||
|
||||
- **Manual Dispatch**: Use `workflow_dispatch` for testing
|
||||
- **Log Analysis**: Review step outputs for error details
|
||||
- **Artifact Inspection**: Download build artifacts for verification
|
||||
- **Package Logs**: Check package activity in GitHub UI
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Planned Features
|
||||
|
||||
- **SLSA Integration**: Enhanced build attestation
|
||||
- **Dependency Review**: Automated dependency vulnerability checking
|
||||
- **Performance Testing**: Load testing integration
|
||||
- **Multi-environment Deployment**: Staging and production separation
|
||||
|
||||
### Scalability Considerations
|
||||
|
||||
- **Self-hosted Runners**: For resource-intensive jobs
|
||||
- **Job Parallelization**: Further optimization of concurrent execution
|
||||
- **Cache Optimization**: Advanced caching strategies
|
||||
|
||||
## Docker Image Usage
|
||||
|
||||
### Pulling Images
|
||||
|
||||
Pull the latest image:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/<owner>/<repository>:latest
|
||||
```
|
||||
|
||||
Pull a specific version:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/<owner>/<repository>:1.2.3
|
||||
```
|
||||
|
||||
### Running Locally
|
||||
|
||||
Run the container:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name tercul-backend \
|
||||
-p 8080:8080 \
|
||||
-e DATABASE_URL="postgres://..." \
|
||||
ghcr.io/<owner>/<repository>:latest
|
||||
```
|
||||
|
||||
### Docker Swarm Deployment
|
||||
|
||||
Deploy as a stack:
|
||||
|
||||
```bash
|
||||
docker stack deploy -c docker-compose.yml tercul
|
||||
```
|
||||
|
||||
Update running service:
|
||||
|
||||
```bash
|
||||
docker service update \
|
||||
--image ghcr.io/<owner>/<repository>:1.2.3 \
|
||||
tercul_backend
|
||||
```
|
||||
|
||||
### Verifying Attestations
|
||||
|
||||
Verify build provenance:
|
||||
|
||||
```bash
|
||||
gh attestation verify \
|
||||
oci://ghcr.io/<owner>/<repository>:latest \
|
||||
--owner <owner>
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
When modifying workflows:
|
||||
|
||||
1. Test changes using `workflow_dispatch`
|
||||
2. Ensure backward compatibility
|
||||
3. Update this documentation
|
||||
4. Follow security best practices
|
||||
5. Use semantic versioning for action references
|
||||
6. Test Docker builds locally before pushing
|
||||
7. Verify package permissions after changes
|
||||
8. Review CodeQL alerts before merging PRs
|
||||
9. Update query packs regularly for latest security rules
|
||||
10. Test configuration changes with `workflow_dispatch`
|
||||
|
||||
## CodeQL Advanced Configuration
|
||||
|
||||
### Custom Configuration File
|
||||
|
||||
For complex CodeQL setups, use a configuration file (`.github/codeql/codeql-config.yml`):
|
||||
|
||||
```yaml
|
||||
name: "CodeQL Config"
|
||||
|
||||
# Disable default queries to run only custom queries
|
||||
disable-default-queries: false
|
||||
|
||||
# Specify query packs
|
||||
packs:
|
||||
- scope/go-security-pack
|
||||
- scope/go-compliance-pack@1.2.3
|
||||
|
||||
# Add custom queries
|
||||
queries:
|
||||
- uses: security-and-quality
|
||||
- uses: ./custom-queries
|
||||
|
||||
# Filter queries by severity
|
||||
query-filters:
|
||||
- exclude:
|
||||
problem.severity:
|
||||
- warning
|
||||
- recommendation
|
||||
- exclude:
|
||||
id: go/redundant-assignment
|
||||
|
||||
# Scan specific directories
|
||||
paths:
|
||||
- internal
|
||||
- cmd
|
||||
- pkg
|
||||
|
||||
paths-ignore:
|
||||
- "**/*_test.go"
|
||||
- vendor
|
||||
- "**/testdata/**"
|
||||
|
||||
# Extend threat model (preview)
|
||||
threat-models: local
|
||||
```
|
||||
|
||||
Reference the config in your workflow:
|
||||
|
||||
```yaml
|
||||
- uses: github/codeql-action/init@v3
|
||||
with:
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
```
|
||||
|
||||
### Inline Configuration
|
||||
|
||||
Alternatively, specify configuration inline:
|
||||
|
||||
```yaml
|
||||
- uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: go
|
||||
config: |
|
||||
disable-default-queries: false
|
||||
queries:
|
||||
- uses: security-extended
|
||||
query-filters:
|
||||
- exclude:
|
||||
problem.severity:
|
||||
- recommendation
|
||||
```
|
||||
|
||||
### Scheduling CodeQL Scans
|
||||
|
||||
Run CodeQL on a schedule for regular security audits:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
schedule:
|
||||
# Run at 14:20 UTC every Monday
|
||||
- cron: '20 14 * * 1'
|
||||
```
|
||||
|
||||
### Avoiding Unnecessary Scans
|
||||
|
||||
Skip CodeQL for specific file changes:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '**/*.txt'
|
||||
- 'docs/**'
|
||||
```
|
||||
|
||||
### Analysis Categories
|
||||
|
||||
Categorize multiple analyses in monorepos:
|
||||
|
||||
```yaml
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "backend-api"
|
||||
```
|
||||
|
||||
### External Query Packs
|
||||
|
||||
Use query packs from GitHub Enterprise Server:
|
||||
|
||||
```yaml
|
||||
- uses: github/codeql-action/init@v3
|
||||
with:
|
||||
registries: |
|
||||
- url: https://containers.GHEHOSTNAME/v2/
|
||||
packages:
|
||||
- my-company/*
|
||||
token: ${{ secrets.GHES_TOKEN }}
|
||||
packs: my-company/go-queries
|
||||
```
|
||||
|
||||
### Query Suite Examples
|
||||
|
||||
**Security-focused**:
|
||||
|
||||
```yaml
|
||||
queries:
|
||||
- uses: security-extended
|
||||
```
|
||||
|
||||
**Quality and security**:
|
||||
|
||||
```yaml
|
||||
queries:
|
||||
- uses: security-and-quality
|
||||
```
|
||||
|
||||
**Custom suite**:
|
||||
|
||||
```yaml
|
||||
queries:
|
||||
- uses: ./custom-queries/critical-security.qls
|
||||
```
|
||||
|
||||
## Advanced Workflow Techniques
|
||||
|
||||
### Workflow Commands
|
||||
|
||||
GitHub Actions supports workflow commands for advanced functionality:
|
||||
|
||||
#### Debug Logging
|
||||
|
||||
Enable detailed debugging with the `ACTIONS_STEP_DEBUG` secret:
|
||||
|
||||
```yaml
|
||||
- name: Debug step
|
||||
run: echo "::debug::Detailed debugging information"
|
||||
```
|
||||
|
||||
#### Annotations
|
||||
|
||||
Create annotations for notices, warnings, and errors:
|
||||
|
||||
```yaml
|
||||
# Notice annotation
|
||||
- run: echo "::notice file=app.go,line=10::Consider refactoring"
|
||||
|
||||
# Warning annotation
|
||||
- run: echo "::warning file=main.go,line=5,col=10::Deprecated function"
|
||||
|
||||
# Error annotation
|
||||
- run: echo "::error file=handler.go,line=20,title=Build Error::Missing import"
|
||||
```
|
||||
|
||||
#### Grouping Log Lines
|
||||
|
||||
Organize logs with collapsible groups:
|
||||
|
||||
```yaml
|
||||
- name: Build application
|
||||
run: |
|
||||
echo "::group::Compiling Go code"
|
||||
go build -v ./...
|
||||
echo "::endgroup::"
|
||||
```
|
||||
|
||||
#### Masking Secrets
|
||||
|
||||
Prevent sensitive values from appearing in logs:
|
||||
|
||||
```yaml
|
||||
- name: Generate token
|
||||
run: |
|
||||
TOKEN=$(generate_token)
|
||||
echo "::add-mask::$TOKEN"
|
||||
echo "TOKEN=$TOKEN" >> $GITHUB_ENV
|
||||
```
|
||||
|
||||
#### Job Summaries
|
||||
|
||||
Add Markdown summaries to workflow runs:
|
||||
|
||||
```yaml
|
||||
- name: Test summary
|
||||
run: |
|
||||
echo "### Test Results :white_check_mark:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Total: 150 tests" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Passed: 148" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Failed: 2" >> $GITHUB_STEP_SUMMARY
|
||||
```
|
||||
|
||||
### Environment Files
|
||||
|
||||
Use environment files for dynamic configuration:
|
||||
|
||||
```yaml
|
||||
# Set environment variable for subsequent steps
|
||||
- name: Set build info
|
||||
run: |
|
||||
echo "BUILD_TIME=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
|
||||
echo "COMMIT_SHA=${GITHUB_SHA:0:7}" >> $GITHUB_ENV
|
||||
|
||||
# Use in later steps
|
||||
- name: Deploy
|
||||
run: echo "Deploying $COMMIT_SHA built at $BUILD_TIME"
|
||||
```
|
||||
|
||||
### Output Parameters
|
||||
|
||||
Share data between steps:
|
||||
|
||||
```yaml
|
||||
- name: Calculate version
|
||||
id: version
|
||||
run: echo "VERSION=1.2.3" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Use version
|
||||
run: echo "Building version ${{ steps.version.outputs.VERSION }}"
|
||||
```
|
||||
|
||||
### Multiline Values
|
||||
|
||||
Handle multiline strings safely:
|
||||
|
||||
```yaml
|
||||
- name: Store API response
|
||||
run: |
|
||||
{
|
||||
echo 'API_RESPONSE<<EOF'
|
||||
curl https://api.example.com/data
|
||||
echo EOF
|
||||
} >> $GITHUB_ENV
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
||||
- [Go CI/CD Best Practices](https://github.com/golang/go/wiki/Go-Release-Cycle)
|
||||
- [Security Hardening Guide](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions)
|
||||
- [Dependency Caching](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows)
|
||||
- [Workflow Commands Reference](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions)
|
||||
- [Publishing Packages with Actions](https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions)
|
||||
- [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry)
|
||||
- [Artifact Attestations](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)
|
||||
- [CodeQL Configuration Reference](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning)
|
||||
- [CodeQL Query Suites](https://docs.github.com/en/code-security/code-scanning/managing-your-code-scanning-configuration/codeql-query-suites)
|
||||
- [CodeQL CLI Reference](https://docs.github.com/en/code-security/codeql-cli)
|
||||
46
.github/workflows/build.yml
vendored
Normal file
46
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
jobs:
|
||||
build-binary:
|
||||
name: Build Binary
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
attestations: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Verify dependencies
|
||||
run: go mod verify
|
||||
|
||||
- name: Build application
|
||||
run: |
|
||||
go build -v -o bin/tercul-backend ./cmd
|
||||
ls -la bin/
|
||||
|
||||
- name: Test binary
|
||||
run: ./bin/tercul-backend --help || echo "Binary built successfully"
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tercul-backend-binary
|
||||
path: bin/
|
||||
retention-days: 30
|
||||
203
.github/workflows/ci-cd.yml
vendored
203
.github/workflows/ci-cd.yml
vendored
@ -1,203 +0,0 @@
|
||||
name: CI/CD Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
jobs:
|
||||
# Security scanning with CodeQL (only on main branch pushes)
|
||||
security-scan:
|
||||
name: Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: go
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Build
|
||||
run: go build -v ./...
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
# Linting (runs on PRs and pushes)
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Tidy modules
|
||||
run: go mod tidy
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: latest
|
||||
args: --timeout=5m ./...
|
||||
|
||||
# Testing and coverage (runs on PRs and pushes)
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: testdb
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- 6379:6379
|
||||
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Run tests with coverage
|
||||
run: |
|
||||
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
|
||||
go tool cover -html=coverage.out -o coverage.html
|
||||
|
||||
- name: Upload coverage reports
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: coverage.html
|
||||
retention-days: 30
|
||||
|
||||
# Build and verify (runs on PRs and pushes)
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
attestations: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Verify dependencies
|
||||
run: go mod verify
|
||||
|
||||
- name: Build application
|
||||
run: |
|
||||
go build -v -o bin/tercul-backend ./cmd
|
||||
ls -la bin/
|
||||
|
||||
- name: Test build
|
||||
run: ./bin/tercul-backend --help || echo "Binary built successfully"
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: terbul-backend-binary
|
||||
path: bin/
|
||||
retention-days: 30
|
||||
|
||||
# Matrix testing across Go versions (only on main branch pushes)
|
||||
test-matrix:
|
||||
name: Test Matrix (Go ${{ matrix.go-version }})
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: ["1.22", "1.23", "1.24", "1.25"]
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: testdb
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- 6379:6379
|
||||
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Run tests
|
||||
run: go test -v -race ./...
|
||||
|
||||
- name: Build
|
||||
run: go build -v ./...
|
||||
60
.github/workflows/deploy.yml
vendored
Normal file
60
.github/workflows/deploy.yml
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Version to deploy (e.g., v1.2.3)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
deploy-production:
|
||||
name: Deploy to Production
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: production
|
||||
url: https://tercul.example.com
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Extract version
|
||||
id: version
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
echo "VERSION=${{ inputs.version }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Deploy to Docker Swarm
|
||||
env:
|
||||
SWARM_HOST: ${{ secrets.SWARM_HOST }}
|
||||
SWARM_SSH_KEY: ${{ secrets.SWARM_SSH_KEY }}
|
||||
IMAGE_TAG: ${{ steps.version.outputs.VERSION }}
|
||||
run: |
|
||||
# Uncomment and configure for actual Docker Swarm deployment
|
||||
# echo "$SWARM_SSH_KEY" > swarm_key
|
||||
# chmod 600 swarm_key
|
||||
# ssh -i swarm_key -o StrictHostKeyChecking=no \
|
||||
# deploy@$SWARM_HOST \
|
||||
# "docker service update \
|
||||
# --image ghcr.io/${{ github.repository }}:${IMAGE_TAG} \
|
||||
# tercul-backend"
|
||||
# rm swarm_key
|
||||
|
||||
echo "Deploying version ${{ steps.version.outputs.VERSION }} to production"
|
||||
echo "Image: ghcr.io/${{ github.repository }}:${IMAGE_TAG}"
|
||||
|
||||
- name: Deployment summary
|
||||
run: |
|
||||
echo "### Deployment Complete :rocket:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Version**: ${{ steps.version.outputs.VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Image**: ghcr.io/${{ github.repository }}:${{ steps.version.outputs.VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Environment**: Production" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Deployed at**: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
|
||||
@ -1,13 +1,15 @@
|
||||
name: Go CD
|
||||
name: Docker Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
tags: ["v*"]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build and Push Docker Image
|
||||
build-image:
|
||||
name: Build Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@ -36,6 +38,7 @@ jobs:
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=ref,event=tag
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
@ -46,7 +49,7 @@ jobs:
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
@ -54,32 +57,9 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
- name: Generate artifact attestation
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/attest-build-provenance@v3
|
||||
with:
|
||||
subject-name: ghcr.io/${{ github.repository}}
|
||||
subject-digest: ${{ steps.push.outputs.digest }}
|
||||
push-to-registry: true
|
||||
|
||||
deploy:
|
||||
name: Deploy to Production
|
||||
needs: build-and-push
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Extract tag name
|
||||
id: tag
|
||||
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
|
||||
# This step is a placeholder for deployment logic
|
||||
# Replace with your actual deployment mechanism (SSH, kubectl, etc.)
|
||||
- name: Deploy to production
|
||||
run: |
|
||||
echo "Deploying version ${{ steps.tag.outputs.TAG }} to production"
|
||||
# Add your deployment commands here
|
||||
env:
|
||||
TAG: ${{ steps.tag.outputs.TAG }}
|
||||
# Add other environment variables needed for deployment
|
||||
@ -1,17 +1,15 @@
|
||||
name: CI
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
branches: [main, develop]
|
||||
|
||||
jobs:
|
||||
lint-and-test:
|
||||
golangci-lint:
|
||||
name: Go Lint
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write # For code scanning
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
@ -28,17 +26,8 @@ jobs:
|
||||
- name: Tidy modules
|
||||
run: go mod tidy
|
||||
|
||||
- name: Lint
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: latest
|
||||
args: --timeout=5m ./...
|
||||
|
||||
- name: Test
|
||||
run: go test -v -race -coverprofile=coverage.out ./...
|
||||
|
||||
- name: Upload coverage
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage
|
||||
path: coverage.out
|
||||
47
.github/workflows/security.yml
vendored
Normal file
47
.github/workflows/security.yml
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
name: Security
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
schedule:
|
||||
# Run CodeQL scan every Monday at 14:20 UTC
|
||||
- cron: "20 14 * * 1"
|
||||
|
||||
jobs:
|
||||
codeql-analysis:
|
||||
name: CodeQL Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: go
|
||||
# Optionally use security-extended for more comprehensive scanning
|
||||
# queries: security-extended
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Build for analysis
|
||||
run: go build -v ./...
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "backend-security"
|
||||
114
.github/workflows/test.yml
vendored
Normal file
114
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
name: Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: testdb
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- 6379:6379
|
||||
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Run tests with coverage
|
||||
run: |
|
||||
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
|
||||
go tool cover -html=coverage.out -o coverage.html
|
||||
|
||||
- name: Generate test summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "### Test Results :test_tube:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Coverage**: See artifact for detailed report" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Race Detection**: Enabled" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Go Version**: 1.25" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Upload coverage reports
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: |
|
||||
coverage.out
|
||||
coverage.html
|
||||
retention-days: 30
|
||||
|
||||
compatibility-matrix:
|
||||
name: Go ${{ matrix.go-version }} Compatibility
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: ["1.22", "1.23", "1.24", "1.25"]
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: testdb
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- 6379:6379
|
||||
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
cache: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Run tests
|
||||
run: go test -v -race ./...
|
||||
|
||||
- name: Build
|
||||
run: go build -v ./...
|
||||
Loading…
Reference in New Issue
Block a user