265 lines
4.8 KiB
Markdown
265 lines
4.8 KiB
Markdown
|
|
---
|
||
|
|
title: "CI/CD Pipeline"
|
||
|
|
linkTitle: "CI/CD"
|
||
|
|
weight: 40
|
||
|
|
description: >
|
||
|
|
Automated testing and container build process.
|
||
|
|
---
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Our documentation uses a continuous integration and deployment pipeline to ensure quality and automate deployment.
|
||
|
|
|
||
|
|
{{< likec4-view view="cicdPipeline" project="documentation-platform" >}}
|
||
|
|
|
||
|
|
## GitHub Actions Workflow
|
||
|
|
|
||
|
|
The CI/CD pipeline is defined in `.github/workflows/test.yml` and runs on:
|
||
|
|
|
||
|
|
- **Pushes to `main` branch**
|
||
|
|
- **Pull requests to `main` branch**
|
||
|
|
|
||
|
|
### Workflow Steps
|
||
|
|
|
||
|
|
#### 1. Checkout Code
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- uses: actions/checkout@v4
|
||
|
|
with:
|
||
|
|
submodules: recursive
|
||
|
|
fetch-depth: 0
|
||
|
|
```
|
||
|
|
|
||
|
|
- Clones repository with full history
|
||
|
|
- Includes Git submodules (Hugo modules)
|
||
|
|
|
||
|
|
#### 2. Setup Hugo
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- name: Setup Hugo
|
||
|
|
uses: peaceiris/actions-hugo@v3
|
||
|
|
with:
|
||
|
|
hugo-version: 'latest'
|
||
|
|
extended: true
|
||
|
|
```
|
||
|
|
|
||
|
|
- Installs Hugo Extended
|
||
|
|
- Uses latest stable version
|
||
|
|
|
||
|
|
#### 3. Setup Node.js
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- name: Setup Node
|
||
|
|
uses: actions/setup-node@v4
|
||
|
|
with:
|
||
|
|
node-version: '24'
|
||
|
|
cache: 'npm'
|
||
|
|
```
|
||
|
|
|
||
|
|
- Installs Node.js v24
|
||
|
|
- Caches npm dependencies for faster builds
|
||
|
|
|
||
|
|
#### 4. Install Dependencies
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm ci
|
||
|
|
go install github.com/wjdp/htmltest@latest
|
||
|
|
```
|
||
|
|
|
||
|
|
- Installs npm packages (markdownlint, htmlvalidate)
|
||
|
|
- Installs htmltest for link checking
|
||
|
|
|
||
|
|
#### 5. Run Tests
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm run test:build
|
||
|
|
npm run test:markdown
|
||
|
|
npm run test:html
|
||
|
|
```
|
||
|
|
|
||
|
|
- Validates Hugo build
|
||
|
|
- Lints Markdown files
|
||
|
|
- Validates HTML output
|
||
|
|
|
||
|
|
#### 6. Link Checking
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- name: Run link checker
|
||
|
|
run: htmltest
|
||
|
|
continue-on-error: true
|
||
|
|
```
|
||
|
|
|
||
|
|
- Checks all links
|
||
|
|
- Continues even if links fail (soft requirement)
|
||
|
|
|
||
|
|
#### 7. Upload Results
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- name: Upload htmltest results
|
||
|
|
uses: actions/upload-artifact@v4
|
||
|
|
if: always()
|
||
|
|
with:
|
||
|
|
name: htmltest-report
|
||
|
|
path: tmp/.htmltest/
|
||
|
|
```
|
||
|
|
|
||
|
|
- Uploads link check report
|
||
|
|
- Available for download from GitHub Actions
|
||
|
|
|
||
|
|
## Container Build Process
|
||
|
|
|
||
|
|
After tests pass, a container image is built:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
task build:oci-image
|
||
|
|
```
|
||
|
|
|
||
|
|
### Build Process
|
||
|
|
|
||
|
|
1. **Reads version information** from `.env.versions`:
|
||
|
|
- `NODE_VERSION`
|
||
|
|
- `GO_VERSION`
|
||
|
|
- `HUGO_VERSION`
|
||
|
|
|
||
|
|
2. **Builds Docker image** using `Dockerfile`:
|
||
|
|
- Multi-stage build
|
||
|
|
- Hugo generates static site
|
||
|
|
- Nginx serves the content
|
||
|
|
|
||
|
|
3. **Tags image** with:
|
||
|
|
- `latest`
|
||
|
|
- Git commit SHA (short)
|
||
|
|
|
||
|
|
### Dockerfile Structure
|
||
|
|
|
||
|
|
```dockerfile
|
||
|
|
# Build stage
|
||
|
|
FROM node:${NODE_VERSION} as builder
|
||
|
|
# Install Hugo, build dependencies
|
||
|
|
# Run: hugo --gc --minify
|
||
|
|
# Output: public/ directory
|
||
|
|
|
||
|
|
# Runtime stage
|
||
|
|
FROM nginx:alpine
|
||
|
|
# Copy public/ to /usr/share/nginx/html/
|
||
|
|
# Configure Nginx
|
||
|
|
```
|
||
|
|
|
||
|
|
### Testing the Container
|
||
|
|
|
||
|
|
```bash
|
||
|
|
task test:oci-image
|
||
|
|
```
|
||
|
|
|
||
|
|
This:
|
||
|
|
|
||
|
|
1. Builds the image
|
||
|
|
2. Starts container on port 8080
|
||
|
|
3. Tests HTTP endpoint
|
||
|
|
4. Cleans up container
|
||
|
|
|
||
|
|
## Package.json Scripts
|
||
|
|
|
||
|
|
The `package.json` defines test scripts:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"scripts": {
|
||
|
|
"test:build": "hugo --gc --minify --logLevel info",
|
||
|
|
"test:markdown": "markdownlint 'content/**/*.md'",
|
||
|
|
"test:html": "htmlvalidate 'public/**/*.html'"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Running CI Locally
|
||
|
|
|
||
|
|
Simulate the CI environment locally:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
task ci
|
||
|
|
```
|
||
|
|
|
||
|
|
This runs the same tests as GitHub Actions.
|
||
|
|
|
||
|
|
## Monitoring CI Results
|
||
|
|
|
||
|
|
### Successful Build
|
||
|
|
|
||
|
|
✅ All tests pass → Ready to deploy
|
||
|
|
|
||
|
|
### Failed Build
|
||
|
|
|
||
|
|
❌ Tests fail:
|
||
|
|
|
||
|
|
1. Click on the failed workflow in GitHub Actions
|
||
|
|
2. Expand the failed step
|
||
|
|
3. Read the error message
|
||
|
|
4. Fix locally: `task test:<specific-test>`
|
||
|
|
5. Commit and push fix
|
||
|
|
|
||
|
|
### Viewing Artifacts
|
||
|
|
|
||
|
|
1. Go to GitHub Actions
|
||
|
|
2. Click on workflow run
|
||
|
|
3. Scroll to "Artifacts" section
|
||
|
|
4. Download `htmltest-report`
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
1. **Don't push to main directly** - Use feature branches and PRs
|
||
|
|
2. **Wait for CI before merging** - Green checkmark required
|
||
|
|
3. **Fix broken builds immediately** - Don't let main stay red
|
||
|
|
4. **Review CI logs** - Understand why tests fail
|
||
|
|
5. **Update dependencies** - Keep versions current in `.env.versions`
|
||
|
|
|
||
|
|
## Continuous Deployment
|
||
|
|
|
||
|
|
After successful CI:
|
||
|
|
|
||
|
|
1. Container image is built
|
||
|
|
2. Image is pushed to registry
|
||
|
|
3. Deployment process begins (see [Publishing](../publishing/))
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Tests pass locally but fail in CI
|
||
|
|
|
||
|
|
**Possible causes:**
|
||
|
|
|
||
|
|
- Different Hugo version
|
||
|
|
- Different Node.js version
|
||
|
|
- Missing dependencies
|
||
|
|
- Environment-specific issues
|
||
|
|
|
||
|
|
**Solution:** Check versions in `.env.versions` and ensure local matches CI
|
||
|
|
|
||
|
|
### Build timeouts
|
||
|
|
|
||
|
|
**Possible causes:**
|
||
|
|
|
||
|
|
- Link checker taking too long
|
||
|
|
- Large number of external links
|
||
|
|
|
||
|
|
**Solution:**
|
||
|
|
|
||
|
|
- Use `continue-on-error: true` for link checks
|
||
|
|
- Configure `.htmltest.yml` to skip slow checks
|
||
|
|
|
||
|
|
### Cache issues
|
||
|
|
|
||
|
|
**Solution:** Clear GitHub Actions cache:
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- uses: actions/cache@v4
|
||
|
|
with:
|
||
|
|
path: ~/.npm
|
||
|
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||
|
|
```
|
||
|
|
|
||
|
|
Update the cache key to force refresh.
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
Learn about [deployment to Edge environment](../publishing/).
|