Skip to content

chore: pin cube-link to tobedeleted/improved-shacl-shapes #88

chore: pin cube-link to tobedeleted/improved-shacl-shapes

chore: pin cube-link to tobedeleted/improved-shacl-shapes #88

Workflow file for this run

name: Main CI/CD Pipeline
on:
push:
branches:
- develop-graphdb
- master-graphdb
pull_request:
env:
REGISTRY: ghcr.io
# Docker registry names must be lowercase
IMAGE_PREFIX: ghcr.io/swissfederalarchives/lindas-cube-creator
jobs:
# Step 1: Linting
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: "yarn"
- name: Install dependencies
run: yarn install --immutable
- name: Run lint
run: |
yarn lint
yarn workspace @cube-creator/ui lint
# Step 2: Unit Tests
unit-tests:
name: Unit Tests
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: "yarn"
- name: Install dependencies
run: yarn install --immutable
- name: Run unit tests
run: yarn test
- name: Upload coverage
if: always()
uses: codecov/codecov-action@v4
continue-on-error: true
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/**/*.lcov
# Step 3: Build, Smoke Tests, and E2E Tests
integration-tests:
name: Smoke & E2E Tests
runs-on: ubuntu-22.04
needs: [lint, unit-tests]
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: "yarn"
- name: Install dependencies
run: yarn install --immutable
- name: Build Docker images
run: docker compose -f docker-compose.e2e.yml build --parallel
- name: Start services
run: docker compose -f docker-compose.e2e.yml up -d
- name: Wait for services to be healthy
run: |
echo "⏳ Waiting for all services to be healthy (max 5 minutes)..."
timeout 300 sh -c 'until [ $(docker compose -f docker-compose.e2e.yml ps --format json | grep -c "\"Health\":\"healthy\"") -ge 4 ]; do
echo "⏳ Waiting... ($(docker compose -f docker-compose.e2e.yml ps --format json | grep -c "\"Health\":\"healthy\"") / 4 services healthy)";
sleep 5;
done'
echo "✅ All services are healthy!"
- name: Run smoke tests
run: |
cd smoke-test
chmod +x smoke-tests.sh
./smoke-tests.sh
- name: Run API E2E tests
run: yarn test:e2e
- name: Run UI Smoke Tests
run: cd ui && npx cypress run --spec "tests/e2e/specs/ui-smoke.spec.ts"
# Full UI E2E tests require OIDC authentication - run locally with: cd ui && yarn test:e2e
- name: Show logs on failure
if: failure()
run: docker compose -f docker-compose.e2e.yml logs
- name: Cleanup
if: always()
run: docker compose -f docker-compose.e2e.yml down -v
# Step 4: Build and Publish Docker Images
build-and-publish:
name: Build & Publish Docker Images
runs-on: ubuntu-latest
needs: [integration-tests]
if: github.ref == 'refs/heads/develop-graphdb' && github.event_name == 'push'
timeout-minutes: 45
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
component: [app, api, cli]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get component version
id: version
run: |
case "${{ matrix.component }}" in
app) VERSION=$(node -p "require('./ui/package.json').version") ;;
api) VERSION=$(node -p "require('./apis/core/package.json').version") ;;
cli) VERSION=$(node -p "require('./cli/package.json').version") ;;
esac
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Determine environment and tags
id: tags
run: |
COMPONENT="${{ matrix.component }}"
VERSION="${{ steps.version.outputs.version }}"
IMAGE="${{ env.IMAGE_PREFIX }}-${COMPONENT}"
TIMESTAMP=$(date -u +%Y%m%d%H%M%S)
if [[ "${{ github.ref }}" == "refs/heads/develop-graphdb" ]]; then
TAGS="${IMAGE}:graphdb-test-${VERSION},${IMAGE}:graphdb-test-latest,${IMAGE}:graphdb-test-${TIMESTAMP}"
ENV="test"
elif [[ "${{ github.ref }}" == "refs/heads/master-graphdb" ]]; then
VERSION_MAJOR=$(echo $VERSION | cut -d. -f1)
VERSION_MINOR=$(echo $VERSION | cut -d. -f1-2)
TAGS="${IMAGE}:graphdb-prod-${VERSION},${IMAGE}:graphdb-v${VERSION},${IMAGE}:graphdb-${VERSION},${IMAGE}:graphdb-${VERSION_MINOR},${IMAGE}:graphdb-${VERSION_MAJOR},${IMAGE}:graphdb-latest"
ENV="production"
fi
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "environment=${ENV}" >> $GITHUB_OUTPUT
- name: Build and push Docker image - app
if: matrix.component == 'app'
uses: docker/build-push-action@v6
with:
file: ./app.Dockerfile
context: .
push: true
tags: ${{ steps.tags.outputs.tags }}
build-args: |
COMMIT=${{ github.sha }}
PUBLIC_PATH=/app/
cache-from: type=gha,scope=${{ matrix.component }}
cache-to: type=gha,mode=max,scope=${{ matrix.component }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.version=${{ steps.version.outputs.version }}
environment=${{ steps.tags.outputs.environment }}
- name: Build and push Docker image - api/cli
if: matrix.component != 'app'
uses: docker/build-push-action@v6
with:
file: ./${{ matrix.component }}.Dockerfile
context: .
push: true
tags: ${{ steps.tags.outputs.tags }}
build-args: |
COMMIT=${{ github.sha }}
cache-from: type=gha,scope=${{ matrix.component }}
cache-to: type=gha,mode=max,scope=${{ matrix.component }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.version=${{ steps.version.outputs.version }}
environment=${{ steps.tags.outputs.environment }}
- name: Create Sentry release
if: steps.tags.outputs.environment == 'production'
uses: getsentry/action-release@v1
continue-on-error: true
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: zazuko
SENTRY_PROJECT: lindas-cube-creator-${{ matrix.component }}
with:
version_prefix: lindas-cube-creator-${{ matrix.component }}@
version: ${{ steps.version.outputs.version }}
ignore_empty: true
- name: Output build summary
run: |
echo "## Docker Image Built" >> $GITHUB_STEP_SUMMARY
echo "**Component:** ${{ matrix.component }}" >> $GITHUB_STEP_SUMMARY
echo "**Version:** ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**Environment:** ${{ steps.tags.outputs.environment }}" >> $GITHUB_STEP_SUMMARY
echo "**Tags:** \`${{ steps.tags.outputs.tags }}\`" >> $GITHUB_STEP_SUMMARY
# Final Status Report
status:
name: Pipeline Status
runs-on: ubuntu-latest
needs: [lint, unit-tests, integration-tests, build-and-publish]
if: always()
steps:
- name: Report Status
run: |
echo "# CI/CD Pipeline Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Stage | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Lint | **${{ needs.lint.result }}** |" >> $GITHUB_STEP_SUMMARY
echo "| Unit Tests | **${{ needs.unit-tests.result }}** |" >> $GITHUB_STEP_SUMMARY
echo "| Integration Tests | **${{ needs.integration-tests.result }}** |" >> $GITHUB_STEP_SUMMARY
echo "| Build & Publish | **${{ needs.build-and-publish.result }}** |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "${{ needs.lint.result }}" == "success" ]] && \
[[ "${{ needs.unit-tests.result }}" == "success" ]] && \
[[ "${{ needs.integration-tests.result }}" == "success" ]]; then
echo "✅ **Pipeline Successful** - All tests passed!" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.ref }}" == "refs/heads/develop-graphdb" ]] && [[ "${{ needs.build-and-publish.result }}" == "success" ]]; then
echo "🚀 **Docker images published to GHCR**" >> $GITHUB_STEP_SUMMARY
fi
else
echo "❌ **Pipeline Failed** - Please check the failed stages above" >> $GITHUB_STEP_SUMMARY
fi