feat: test ci #29
Workflow file for this run
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: | | |
| # Check if there are any changes that require versioning | |
| echo "🔍 Checking for changes requiring versioning..." | |
| # Try different strategies to detect changes | |
| CHANGED_PACKAGES=0 | |
| # Strategy 1: Check against last tag (for normal releases) | |
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -n "$LAST_TAG" ]; then | |
| echo "📌 Last tag found: $LAST_TAG" | |
| CHANGED_PACKAGES=$(melos list --since="$LAST_TAG" --json 2>/dev/null | jq -r '.[].name' | wc -l || echo "0") | |
| echo "📦 Found $CHANGED_PACKAGES packages with changes since $LAST_TAG" | |
| fi | |
| # Strategy 2: If no changes found or no tags, check against develop branch merge base | |
| if [ "$CHANGED_PACKAGES" -eq 0 ]; then | |
| echo "🔄 No changes found with tags, trying merge-base with develop..." | |
| MERGE_BASE=$(git merge-base HEAD origin/develop 2>/dev/null || echo "") | |
| if [ -n "$MERGE_BASE" ] && [ "$MERGE_BASE" != "$(git rev-parse HEAD)" ]; then | |
| echo "🔗 Merge base with develop: $MERGE_BASE" | |
| CHANGED_PACKAGES=$(melos list --since="$MERGE_BASE" --json 2>/dev/null | jq -r '.[].name' | wc -l || echo "0") | |
| echo "📦 Found $CHANGED_PACKAGES packages with changes since merge base" | |
| fi | |
| fi | |
| # Strategy 3: If still no changes, check if this is first release (no previous packages published) | |
| if [ "$CHANGED_PACKAGES" -eq 0 ]; then | |
| echo "🆕 Checking if this is a first release..." | |
| # Count all packages (for first release, we want to publish everything) | |
| ALL_PACKAGES=$(melos list --json 2>/dev/null | jq -r '.[].name' | wc -l || echo "0") | |
| # Check if any packages exist - if yes, this might be first release | |
| if [ "$ALL_PACKAGES" -gt 0 ]; then | |
| echo "📦 Found $ALL_PACKAGES total packages" | |
| # Check if we have any git tags at all | |
| TAG_COUNT=$(git tag -l | wc -l || echo "0") | |
| if [ "$TAG_COUNT" -eq 0 ]; then | |
| echo "🎉 No previous tags found - treating as first release" | |
| CHANGED_PACKAGES=$ALL_PACKAGES | |
| else | |
| echo "🔍 Tags exist but no changes detected - checking HEAD~1 as fallback" | |
| CHANGED_PACKAGES=$(melos list --since=HEAD~1 --json 2>/dev/null | jq -r '.[].name' | wc -l || echo "0") | |
| fi | |
| fi | |
| fi | |
| echo "changed_packages=$CHANGED_PACKAGES" >> $GITHUB_OUTPUT | |
| echo "✅ Final result: $CHANGED_PACKAGES packages with changes" | |
| # Debug: List the changed packages if any | |
| if [ "$CHANGED_PACKAGES" -gt 0 ]; then | |
| echo "📋 Changed packages:" | |
| if [ -n "$LAST_TAG" ]; then | |
| melos list --since="$LAST_TAG" --long 2>/dev/null || echo "Unable to list changed packages" | |
| elif [ -n "$MERGE_BASE" ] && [ "$MERGE_BASE" != "$(git rev-parse HEAD)" ]; then | |
| melos list --since="$MERGE_BASE" --long 2>/dev/null || echo "Unable to list changed packages" | |
| else | |
| melos list --long 2>/dev/null || echo "Unable to list 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 packages based on conventional commits | |
| melos version --yes --all | |
| - 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 |