feat: wip #18
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: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| FLUTTER_VERSION: "3.35.0" | |
| MELOS_VERSION: "6.0.0" | |
| jobs: | |
| # Job 1: Analyze and validate code quality | |
| analyze: | |
| name: 📊 Code Analysis | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: 📚 Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history for conventional commits | |
| - name: 🐦 Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| cache: true | |
| - name: 📦 Get dependencies | |
| run: flutter pub global activate melos ${{ env.MELOS_VERSION }} | |
| - name: 🏗️ Bootstrap monorepo | |
| run: melos bootstrap | |
| - name: 🔍 Analyze code | |
| run: melos run analyze | |
| - name: 📝 Check formatting | |
| run: melos run format | |
| # Job 2: Run all tests | |
| test: | |
| name: 🧪 Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: [analyze] | |
| steps: | |
| - name: 📚 Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: 🐦 Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| cache: true | |
| - name: 📦 Get dependencies | |
| run: flutter pub global activate melos ${{ env.MELOS_VERSION }} | |
| - name: 🏗️ Bootstrap monorepo | |
| run: melos bootstrap | |
| - name: 🧪 Run tests | |
| run: melos run test:all | |
| - name: 📊 Upload coverage | |
| uses: codecov/codecov-action@v3 | |
| if: success() | |
| with: | |
| files: ./coverage/lcov.info | |
| # Job 3: Build packages | |
| build: | |
| name: 🏗️ Build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: [analyze] | |
| steps: | |
| - name: 📚 Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: 🐦 Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| cache: true | |
| - name: 📦 Get dependencies | |
| run: flutter pub global activate melos ${{ env.MELOS_VERSION }} | |
| - name: 🏗️ Bootstrap monorepo | |
| run: melos bootstrap | |
| - name: 🔨 Build packages | |
| run: melos run build_runner | |
| - name: 📱 Build example apps | |
| run: melos run build:all | |
| continue-on-error: true # Some packages might not have example apps | |
| # Job 4: Version and publish (only on main branch) | |
| version-and-publish: | |
| name: 🚀 Version & Publish | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: [analyze, test, build] | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| permissions: | |
| contents: write | |
| packages: write | |
| pull-requests: write | |
| steps: | |
| - name: 📚 Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: 🐦 Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| cache: true | |
| - name: 📦 Get dependencies | |
| run: flutter pub global activate melos ${{ env.MELOS_VERSION }} | |
| - name: 🏗️ Bootstrap monorepo | |
| run: melos bootstrap | |
| - name: 🏷️ Check for changes requiring versioning | |
| id: check-changes | |
| run: | | |
| echo "🔍 Checking for changes requiring versioning..." | |
| # Simple approach: check against origin/develop (like in PR workflow) | |
| # This works for both first releases and merges | |
| CHANGED_PACKAGES=$(melos list --since=origin/develop --json 2>/dev/null | jq -r '.[].name' | wc -l || echo "0") | |
| # If no changes found, it might be because we're on develop or first commit | |
| if [ "$CHANGED_PACKAGES" -eq 0 ]; then | |
| echo "🔄 No changes since origin/develop, checking if this is a first release..." | |
| # Check if we have any package tags | |
| PACKAGE_TAGS=$(git tag -l "*@*" | wc -l || echo "0") | |
| if [ "$PACKAGE_TAGS" -eq 0 ]; then | |
| echo "🎉 No package tags found - treating as first release" | |
| CHANGED_PACKAGES=$(melos list --json 2>/dev/null | jq -r '.[].name' | wc -l || echo "0") | |
| fi | |
| fi | |
| echo "changed_packages=$CHANGED_PACKAGES" >> $GITHUB_OUTPUT | |
| echo "📦 Found $CHANGED_PACKAGES packages with changes" | |
| # List changed packages for debugging | |
| if [ "$CHANGED_PACKAGES" -gt 0 ]; then | |
| echo "📋 Changed packages:" | |
| if [ "$PACKAGE_TAGS" -eq 0 ]; then | |
| echo "First release - all packages:" | |
| melos list --long 2>/dev/null || echo "Unable to list packages" | |
| else | |
| melos list --since=origin/develop --long 2>/dev/null || echo "Unable to list changed packages" | |
| fi | |
| fi | |
| - name: 🔄 Version packages | |
| if: steps.check-changes.outputs.changed_packages > 0 | |
| run: | | |
| # Configure git for automated commits | |
| git config --global user.name "github-actions[bot]" | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| # Version only changed packages based on conventional commits | |
| echo "🔄 Versioning packages..." | |
| # Check if we have package tags (not first release) | |
| PACKAGE_TAGS=$(git tag -l "*@*" | wc -l || echo "0") | |
| if [ "$PACKAGE_TAGS" -eq 0 ]; then | |
| echo "🎉 First release - versioning all packages" | |
| melos version --yes --all | |
| else | |
| echo "📦 Versioning changed packages only" | |
| # Version only packages that have changes since origin/develop | |
| melos version --yes | |
| fi | |
| - name: 📝 Generate changelogs | |
| if: steps.check-changes.outputs.changed_packages > 0 | |
| run: | | |
| # Generate individual package changelogs | |
| melos exec --no-private -- "echo 'Generating changelog for \$MELOS_PACKAGE_NAME'" | |
| # Update workspace changelog | |
| echo "# Pillar Monorepo Changelog" > CHANGELOG.md | |
| echo "" >> CHANGELOG.md | |
| echo "This file tracks changes across all packages in the Pillar monorepo." >> CHANGELOG.md | |
| echo "" >> CHANGELOG.md | |
| echo "## $(date '+%Y-%m-%d')" >> CHANGELOG.md | |
| echo "" >> CHANGELOG.md | |
| # Add package versions to workspace changelog | |
| melos list --long --json | jq -r '.[] | "- **\(.name)** v\(.version)"' >> CHANGELOG.md | |
| - name: 🏷️ Create release tags | |
| if: steps.check-changes.outputs.changed_packages > 0 | |
| run: | | |
| # Get the list of packages that were versioned | |
| VERSIONED_PACKAGES=$(melos list --json | jq -r '.[].name') | |
| for package in $VERSIONED_PACKAGES; do | |
| VERSION=$(melos list --json | jq -r ".[] | select(.name == \"$package\") | .version") | |
| if [ ! -z "$VERSION" ] && [ "$VERSION" != "null" ]; then | |
| echo "Creating tag for $package@$VERSION" | |
| git tag "$package@$VERSION" -m "Release $package version $VERSION" | |
| fi | |
| done | |
| - name: 📤 Push changes and tags | |
| if: steps.check-changes.outputs.changed_packages > 0 | |
| run: | | |
| git push origin main | |
| git push origin --tags | |
| - name: 📦 Publish to pub.dev | |
| if: steps.check-changes.outputs.changed_packages > 0 | |
| env: | |
| PUB_CREDENTIALS: ${{ secrets.PUB_CREDENTIALS }} | |
| run: | | |
| # Setup pub.dev credentials for auto-refresh | |
| if [ -n "$PUB_CREDENTIALS" ]; then | |
| echo "🔐 Setting up pub.dev credentials with auto-refresh..." | |
| mkdir -p ~/.pub-cache | |
| echo "$PUB_CREDENTIALS" > ~/.pub-cache/credentials.json | |
| echo "✅ Credentials configured with refresh token" | |
| else | |
| echo "⚠️ PUB_CREDENTIALS not configured, skipping publish" | |
| exit 1 | |
| fi | |
| # Publish packages (dart pub will auto-refresh token if needed) | |
| echo "📦 Publishing packages to pub.dev..." | |
| melos publish --no-dry-run --yes || echo "⚠️ Some packages may have failed to publish" | |
| - name: 📋 Create GitHub release | |
| if: steps.check-changes.outputs.changed_packages > 0 | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: "release-$(date +'%Y%m%d-%H%M%S')" | |
| release_name: "Pillar Release $(date +'%Y-%m-%d %H:%M:%S')" | |
| body: | | |
| ## 🚀 Automated Release | |
| This release was automatically generated by our CI/CD pipeline. | |
| ### 📦 Updated Packages | |
| $(melos list --long | grep -v "PRIVATE" || echo "No public packages updated") | |
| ### 🔄 Changes | |
| See individual package changelogs for detailed changes. | |
| --- | |
| Generated on $(date) | |
| draft: false | |
| prerelease: false | |
| # Job 5: Notify on failure | |
| notify-failure: | |
| name: 📢 Notify Failure | |
| runs-on: ubuntu-latest | |
| needs: [analyze, test, build, version-and-publish] | |
| if: failure() && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: 📢 Send notification | |
| run: | | |
| echo "🚨 CI/CD Pipeline failed for main branch" | |
| echo "Please check the logs and fix the issues" | |
| # Add Slack/Discord/Email notification here if needed |