CI/CD Build and Release Process
Yew Search uses both GitHub Actions and GitLab CI for building and publishing Docker images. Both CI systems support versioned releases using CalVer (YYYY.MM.DD.patch) format.
Overview
When you trigger a manual build, you can optionally specify a CalVer version tag. All builds are automatically tagged as :latest, and if you provide a VERSION_TAG, the image is ALSO tagged with your CalVer version.
All builds produce these tags:
- Commit SHA - Unique identifier for this exact build (e.g.,
:9124435e) :latest- Always applied to every build- CalVer version - Optional, only if you specify VERSION_TAG (e.g.,
:2025.01.27.0)
Example:
- Build without VERSION_TAG → Tagged as
:9124435e+:latest - Build with VERSION_TAG=2025.01.27.0 → Tagged as
:9124435e+:latest+:2025.01.27.0
GitLab CI - Triggering Versioned Builds
Available Build Jobs
GitLab CI provides four manual build jobs:
manual-build-backend- Builds the NestJS backend APImanual-build-frontend- Builds the Svelte frontend applicationmanual-build-docs- Builds the documentation sitemanual-build-website- Builds the marketing website
How to Trigger a Build
Step 1: Go to CI/CD Pipelines
Navigate to your GitLab project:
Your Project → CI/CD → Pipelines
Step 2: Run Pipeline
Click "Run pipeline" button in the top right
Step 3: Set Version Variable (Optional)
In the pipeline configuration:
- Leave "Run for branch name or tag" as
main(or select your desired branch) - Optional: In the Variables section, add a new variable to also tag with a CalVer version:
- Key:
VERSION_TAG - Value: Your CalVer version (e.g.,
2025.01.27.0)
- Key:
Note: All builds are tagged as :latest automatically. VERSION_TAG adds an ADDITIONAL version tag.
Step 4: Run the Build Job
- Click "Run pipeline"
- Wait for pipeline to appear
- Click on the pipeline
- Find the
manual-build-backend(or whichever service you want) job under the "utility" stage - Click the Play button (▶) to trigger the manual job
Example: Building Backend Version 2025.01.27.0
1. Click "Run pipeline"
2. Branch: main
3. Add variable:
- Key: VERSION_TAG
- Value: 2025.01.27.0
4. Click "Run pipeline"
5. In pipeline view, click Play (▶) on "manual-build-backend"
Result: Image will be tagged as:
registry.gitlab.com/your-namespace/yew-monorepo/backend:9124435e(commit SHA)registry.gitlab.com/your-namespace/yew-monorepo/backend:latest(always)registry.gitlab.com/your-namespace/yew-monorepo/backend:2025.01.27.0(your CalVer version)
Building Multiple Services
To build multiple services with the same version:
- Trigger pipeline once with
VERSION_TAG=2025.01.27.0 - Manually trigger all jobs you need:
- Click Play on
manual-build-backend - Click Play on
manual-build-frontend - Click Play on
manual-build-docs - Click Play on
manual-build-website
- Click Play on
All will use the same VERSION_TAG from the pipeline variables.
GitHub Actions - Triggering Versioned Builds
Available Workflows
GitHub Actions provides four manual workflows:
- Build and Push Backend Image - Builds the NestJS backend API
- Build and Push Frontend Image - Builds the Svelte frontend application
- Build and Push Docs Image - Builds the documentation site
- Build and Push Website Image - Builds the marketing website
How to Trigger a Build
Step 1: Go to Actions Tab
Navigate to your GitHub repository:
Your Repository → Actions tab
Step 2: Select Workflow
In the left sidebar, click on the workflow you want to run (e.g., "Build and Push Backend Image")
Step 3: Run Workflow
- Click the "Run workflow" button (top right of workflow runs list)
- A dropdown will appear with:
- Branch: Select branch to run from (typically
main) - Tag to use for Docker image: Enter your version or leave as
latest
- Branch: Select branch to run from (typically
Step 4: Specify Version
In the "Tag to use for Docker image" field:
For versioned release:
2025.01.27.0
For latest:
latest
(or leave blank to use default)
Step 5: Trigger Build
Click the green "Run workflow" button
Example: Building Frontend Version 2025.01.27.0
1. Go to Actions tab
2. Click "Build and Push Frontend Image" (left sidebar)
3. Click "Run workflow" button
4. Branch: main
5. Tag: 2025.01.27.0
6. Click "Run workflow"
Result: Image will be tagged as:
ghcr.io/your-username/frontend:9124435e(commit SHA)ghcr.io/your-username/frontend:2025.01.27.0(your version)
Building Multiple Services
Repeat the process for each service you want to build:
- Run "Build and Push Backend Image" with tag
2025.01.27.0 - Run "Build and Push Frontend Image" with tag
2025.01.27.0 - Run "Build and Push Docs Image" with tag
2025.01.27.0 - Run "Build and Push Website Image" with tag
2025.01.27.0
CalVer Version Format
Yew Search uses Calendar Versioning (CalVer) with the format:
YYYY.MM.DD.patch
Examples
2025.01.27.0- First release on January 27, 20252025.01.27.1- Second release (hotfix) on the same day2025.02.15.0- Release on February 15, 20252026.03.01.0- Release on March 1, 2026
When to Increment
Increment date (YYYY.MM.DD):
- Every new deployment day
- Even if it's just one commit
- Example:
2025.01.27.0→ next day →2025.01.28.0
Increment patch (.patch):
- Multiple releases on the same day
- Usually for hotfixes or urgent deployments
- Example:
2025.01.27.0→ hotfix same day →2025.01.27.1
Generating Today's Version
To generate a version for today:
# Basic version (patch = 0)
date +%Y.%m.%d.0
# Output: 2025.01.27.0
For subsequent releases on the same day, manually increment the patch number.
Best Practices
1. Coordinate Frontend and Backend Releases
Always build frontend and backend with the same version tag:
Backend: registry.gitlab.com/your-namespace/yew-monorepo/backend:2025.01.27.0
Frontend: registry.gitlab.com/your-namespace/yew-monorepo/frontend:2025.01.27.0
This ensures compatibility and makes it clear which versions were released together.
2. Tag Git Commits
After building a release, tag the git commit:
git tag 2025.01.27.0
git push origin 2025.01.27.0
This creates a permanent reference to the code that produced this release.
3. Document Releases
Keep a record of what each release contains:
2025.01.27.0
- Added OAuth reauth functionality
- Fixed sidebar mobile navigation
- Updated polling system for integrations
2025.01.20.0
- Initial Gmail integration polling
- Migration system improvements
4. Test Before Promoting to Latest
If testing a new feature:
- Build with version tag:
2025.01.27.0-beta - Deploy to staging environment
- Test thoroughly
- Build production release:
2025.01.27.0(from main branch)
5. Use Commit SHA for Debugging
If you need to debug a specific build:
# In docker-compose.yml
image: registry.gitlab.com/your-namespace/yew-monorepo/backend:9124435e
This gives you exact reproducibility.
Image Registries
GitLab Container Registry
Location: registry.gitlab.com/your-namespace/yew-monorepo/
Images:
backend:TAGfrontend:TAGdocs:TAGwebsite:TAG
Authentication:
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u your-username --password-stdin
GitHub Container Registry (ghcr.io)
Location: ghcr.io/your-username/
Images:
backend:TAGfrontend:TAGdocs:TAGwebsite:TAG
Authentication:
echo $GITHUB_TOKEN | docker login ghcr.io -u your-username --password-stdin
Viewing Available Tags
GitLab
Navigate to:
Your Project → Packages & Registries → Container Registry
Click on any image to see all available tags.
GitHub
Navigate to:
Your Repository → Packages (right sidebar)
Click on any package to see all available tags.
Troubleshooting
Build Fails with "VERSION_TAG: unbound variable"
Cause: You're running an older version of .gitlab-ci.yml that doesn't support VERSION_TAG
Solution: Pull latest changes from main branch:
git pull origin main
Image Tagged as "latest" When I Specified a Version
Expected behavior on default branch (main):
- Custom version builds are ALSO tagged as
:latest - This ensures
:latestalways points to the newest release
To prevent this: Build from a feature branch instead of main
GitHub Actions: "Tag to use for Docker image" Field Missing
Cause: Your workflow file may be outdated
Solution: Check that your workflow file (.github/workflows/build-*.yml) has the workflow_dispatch input defined:
on:
workflow_dispatch:
inputs:
tag:
description: 'Tag to use for Docker image'
required: false
default: 'latest'
Related Documentation
- Why CalVer? - Explanation of our versioning strategy
- Installation Guide - Using versioned images in docker-compose
- Architecture - System architecture overview