feat: add cross-platform Makefile with self-documenting help system #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: | |
| - '**' # All branches | |
| pull_request: | |
| branches: | |
| - main | |
| - alpha | |
| env: | |
| DOTNET_VERSION: '10.0.x' | |
| PYTHON_VERSION: '3.11' | |
| jobs: | |
| # Job 1: Test and validate on all branches except main | |
| test: | |
| name: Test & Validate | |
| runs-on: ubuntu-latest | |
| if: github.ref != 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history for better analysis | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Build | |
| run: dotnet build --no-restore --configuration Release | |
| - name: Run tests | |
| run: dotnet test --no-build --configuration Release --logger "trx;LogFileName=test-results.trx" --results-directory TestResults | |
| - name: Generate Requirements Matrix | |
| if: always() # Run even if tests fail | |
| run: | | |
| python scripts/generate-requirements-matrix.py \ | |
| --test-results TestResults/test-results.trx \ | |
| --output reports/REQUIREMENTS_MATRIX.md | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results | |
| path: TestResults/test-results.trx | |
| retention-days: 30 | |
| - name: Upload requirements matrix | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: requirements-matrix | |
| path: reports/REQUIREMENTS_MATRIX.md | |
| retention-days: 30 | |
| - name: Docker sanity check | |
| run: | | |
| echo "🐳 Validating Docker Compose configuration..." | |
| docker compose config > /dev/null | |
| echo "✅ Docker Compose configuration is valid" | |
| - name: Check for errors | |
| run: | | |
| if [ -d "bin" ] || [ -d "obj" ]; then | |
| echo "⚠️ Warning: bin/obj directories found in repository" | |
| fi | |
| # Check for common issues | |
| echo "🔍 Running sanity checks..." | |
| # Check appsettings files | |
| find . -name "appsettings*.json" -type f | while read file; do | |
| echo "Validating JSON: $file" | |
| python -m json.tool "$file" > /dev/null || echo "❌ Invalid JSON: $file" | |
| done | |
| echo "✅ Sanity checks completed" | |
| # Job 2: Publish Docker images on main branch | |
| publish: | |
| name: Build & Publish Docker Images | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Extract metadata | |
| id: meta | |
| run: | | |
| echo "version=$(date +'%Y.%m.%d')-${GITHUB_SHA::7}" >> $GITHUB_OUTPUT | |
| echo "date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT | |
| - name: Build and push Web | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: ./src/web | |
| file: ./src/web/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-web:latest | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-web:${{ steps.meta.outputs.version }} | |
| cache-from: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-web:buildcache | |
| cache-to: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-web:buildcache,mode=max | |
| - name: Build and push Auth | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: ./src/Services/Auth | |
| file: ./src/Services/Auth/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-auth:latest | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-auth:${{ steps.meta.outputs.version }} | |
| cache-from: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-auth:buildcache | |
| cache-to: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-auth:buildcache,mode=max | |
| - name: Build and push SysMLStore | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: ./src/Services/SysMLStore | |
| file: ./src/Services/SysMLStore/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-sysmlstore:latest | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-sysmlstore:${{ steps.meta.outputs.version }} | |
| cache-from: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-sysmlstore:buildcache | |
| cache-to: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-sysmlstore:buildcache,mode=max | |
| - name: Build and push SysMLDiagram | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: ./src/Services/SysMLDiagram | |
| file: ./src/Services/SysMLDiagram/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-sysmldiagram:latest | |
| ${{ secrets.DOCKER_USERNAME }}/sysarx-sysmldiagram:${{ steps.meta.outputs.version }} | |
| cache-from: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-sysmldiagram:buildcache | |
| cache-to: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/sysarx-sysmldiagram:buildcache,mode=max | |
| - name: Update Docker Compose with new tags | |
| run: | | |
| sed -i "s|image: .*sysarx-web.*|image: ${{ secrets.DOCKER_USERNAME }}/sysarx-web:${{ steps.meta.outputs.version }}|g" docker-compose.yml | |
| sed -i "s|image: .*sysarx-auth.*|image: ${{ secrets.DOCKER_USERNAME }}/sysarx-auth:${{ steps.meta.outputs.version }}|g" docker-compose.yml | |
| sed -i "s|image: .*sysarx-sysmlstore.*|image: ${{ secrets.DOCKER_USERNAME }}/sysarx-sysmlstore:${{ steps.meta.outputs.version }}|g" docker-compose.yml | |
| sed -i "s|image: .*sysarx-sysmldiagram.*|image: ${{ secrets.DOCKER_USERNAME }}/sysarx-sysmldiagram:${{ steps.meta.outputs.version }}|g" docker-compose.yml | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: v${{ steps.meta.outputs.version }} | |
| name: Release v${{ steps.meta.outputs.version }} | |
| body: | | |
| ## Docker Images Published | |
| - `${{ secrets.DOCKER_USERNAME }}/sysarx-web:${{ steps.meta.outputs.version }}` | |
| - `${{ secrets.DOCKER_USERNAME }}/sysarx-auth:${{ steps.meta.outputs.version }}` | |
| - `${{ secrets.DOCKER_USERNAME }}/sysarx-sysmlstore:${{ steps.meta.outputs.version }}` | |
| - `${{ secrets.DOCKER_USERNAME }}/sysarx-sysmldiagram:${{ steps.meta.outputs.version }}` | |
| **Built:** ${{ steps.meta.outputs.date }} | |
| **Commit:** ${{ github.sha }} | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Deploy notification | |
| run: | | |
| echo "✅ Docker images published successfully!" | |
| echo "📦 Version: ${{ steps.meta.outputs.version }}" | |
| echo "🐳 Images available on Docker Hub" |