Skip to content

fix(dogfood-gate): validate DEED via deed-ecosystem, not a2ml-era nam… #225

fix(dogfood-gate): validate DEED via deed-ecosystem, not a2ml-era nam…

fix(dogfood-gate): validate DEED via deed-ecosystem, not a2ml-era nam… #225

Workflow file for this run

# SPDX-License-Identifier: MPL-2.0
permissions:
actions: read
contents: read
name: CI
on:
push:
branches: [main, master, develop]
tags: ['v*']
pull_request:
branches: [main, master, develop]
workflow_dispatch:
inputs:
run_full_test:
description: 'Run full test suite'
required: false
default: 'false'
type: boolean
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CI: true
COVERAGE: true
jobs:
# Detect project type and configuration
detect:
name: Detect Project Configuration
runs-on: ubuntu-latest
timeout-minutes: 15
outputs:
languages: ${{ steps.detect.outputs.languages }}
primary_language: ${{ steps.detect.outputs.primary_language }}
package_managers: ${{ steps.detect.outputs.package_managers }}
test_frameworks: ${{ steps.detect.outputs.test_frameworks }}
has_nodejs: ${{ steps.detect.outputs.has_nodejs }}
has_python: ${{ steps.detect.outputs.has_python }}
has_go: ${{ steps.detect.outputs.has_go }}
has_rust: ${{ steps.detect.outputs.has_rust }}
has_docker: ${{ steps.detect.outputs.has_docker }}
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Make scripts executable
run: chmod +x ci-scripts/*.sh
- name: Run detection
id: detect
run: |
source ci-scripts/detect.sh
detect_languages
detect_package_managers
detect_test_frameworks
detect_build_systems
echo "languages=$DETECTED_LANGUAGES" >> $GITHUB_OUTPUT
echo "primary_language=$PRIMARY_LANGUAGE" >> $GITHUB_OUTPUT
echo "package_managers=$DETECTED_PACKAGE_MANAGERS" >> $GITHUB_OUTPUT
echo "test_frameworks=$DETECTED_TEST_FRAMEWORKS" >> $GITHUB_OUTPUT
# Set boolean flags for conditional jobs
[[ "$DETECTED_LANGUAGES" == *"javascript"* || "$DETECTED_LANGUAGES" == *"typescript"* ]] && echo "has_nodejs=true" >> $GITHUB_OUTPUT || echo "has_nodejs=false" >> $GITHUB_OUTPUT
[[ "$DETECTED_LANGUAGES" == *"python"* ]] && echo "has_python=true" >> $GITHUB_OUTPUT || echo "has_python=false" >> $GITHUB_OUTPUT
[[ "$DETECTED_LANGUAGES" == *"go"* ]] && echo "has_go=true" >> $GITHUB_OUTPUT || echo "has_go=false" >> $GITHUB_OUTPUT
[[ "$DETECTED_LANGUAGES" == *"rust"* ]] && echo "has_rust=true" >> $GITHUB_OUTPUT || echo "has_rust=false" >> $GITHUB_OUTPUT
[[ -f "Dockerfile" ]] && echo "has_docker=true" >> $GITHUB_OUTPUT || echo "has_docker=false" >> $GITHUB_OUTPUT
# Lint job
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 15
needs: detect
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Setup Node.js
if: needs.detect.outputs.has_nodejs == 'true'
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- name: Setup Python
if: needs.detect.outputs.has_python == 'true'
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
cache: 'pip'
- name: Setup Go
if: needs.detect.outputs.has_go == 'true'
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.22'
cache: true
- name: Setup Rust
if: needs.detect.outputs.has_rust == 'true'
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
with:
components: rustfmt, clippy
- name: Install dependencies
run: |
chmod +x ci-scripts/*.sh
ci-scripts/setup.sh
- name: Run linters
run: ci-scripts/lint.sh
# Test job with matrix for multiple versions
test:
name: Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
needs: detect
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
include:
- os: ubuntu-latest
node-version: '20'
python-version: '3.12'
go-version: '1.22'
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Setup Node.js
if: needs.detect.outputs.has_nodejs == 'true'
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- name: Setup Python
if: needs.detect.outputs.has_python == 'true'
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Setup Go
if: needs.detect.outputs.has_go == 'true'
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: ${{ matrix.go-version }}
cache: true
- name: Setup Rust
if: needs.detect.outputs.has_rust == 'true'
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
- name: Cache dependencies
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
with:
path: |
~/.npm
~/.cache/pip
~/go/pkg/mod
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json', '**/requirements*.txt', '**/go.sum', '**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-deps-
- name: Install dependencies
run: |
chmod +x ci-scripts/*.sh
ci-scripts/setup.sh
- name: Run tests
run: ci-scripts/test.sh --coverage --ci
# Build job
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [detect, lint, test]
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Setup Node.js
if: needs.detect.outputs.has_nodejs == 'true'
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- name: Setup Python
if: needs.detect.outputs.has_python == 'true'
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
- name: Setup Go
if: needs.detect.outputs.has_go == 'true'
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.22'
- name: Setup Rust
if: needs.detect.outputs.has_rust == 'true'
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
- name: Install dependencies
run: |
chmod +x ci-scripts/*.sh
ci-scripts/setup.sh
- name: Build
run: ci-scripts/build.sh --release
- name: Upload build artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: build-artifacts
path: |
dist/
build/
target/release/
retention-days: 7
if-no-files-found: ignore
# Mirror to GitLab (event-driven push mirroring)
mirror:
name: Mirror to GitLab
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [build]
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- name: Setup SSH for GitLab
env:
GITLAB_SSH_PRIVATE_KEY: ${{ secrets.GITLAB_SSH_PRIVATE_KEY }}
run: |
mkdir -p ~/.ssh
echo "$GITLAB_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
- name: Mirror to GitLab
env:
MIRROR_URL: ${{ secrets.GITLAB_MIRROR_URL }}
run: |
chmod +x ci-scripts/*.sh
ci-scripts/sync-mirror.sh --mirror-url "$MIRROR_URL" --push
# Docker build (if Dockerfile exists)
docker:
name: Docker Build
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [detect, build]
if: needs.detect.outputs.has_docker == 'true'
permissions:
contents: read
packages: write
id-token: write
attestations: write
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Login to GitHub Container Registry
if: github.event_name == 'push'
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name: Build and push
id: push
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
with:
context: .
push: ${{ github.event_name == 'push' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Attest container provenance
if: github.event_name == 'push'
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2
with:
subject-name: ghcr.io/${{ github.repository }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
# Release job (on tags)
release:
name: Release
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [build]
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
id-token: write
attestations: write
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Download artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: build-artifacts
path: dist/
- name: Create Release
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
with:
generate_release_notes: true
files: dist/*
- name: Attest build provenance
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2
with:
subject-path: 'dist/*'