From 0fbeca5eb30201c8afea4ab4974a367ebe910014 Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Tue, 23 Sep 2025 16:11:46 +0100 Subject: [PATCH 1/5] ci: add earthly count --- .github/workflows/earthly-count.yml | 185 ++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 .github/workflows/earthly-count.yml diff --git a/.github/workflows/earthly-count.yml b/.github/workflows/earthly-count.yml new file mode 100644 index 000000000..8107b0bd4 --- /dev/null +++ b/.github/workflows/earthly-count.yml @@ -0,0 +1,185 @@ +name: Track Earthly to Earthbuild Progress + +on: + pull_request: + types: [opened, synchronize] + +jobs: + count-earthly: + runs-on: ubuntu-24.04-arm + permissions: + contents: read + pull-requests: write + + steps: + - name: Checkout PR branch + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + with: + fetch-depth: 0 + + - name: Count occurrences in PR branch + id: count_pr + run: | + # Count total occurrences + total_count=$(git grep -i "earthly" 2>/dev/null | wc -l || echo "0") + echo "total_count=$total_count" >> $GITHUB_OUTPUT + + # Count by file type + go_count=$(git grep -i "earthly" -- "*.go" 2>/dev/null | wc -l || echo "0") + md_count=$(git grep -i "earthly" -- "*.md" 2>/dev/null | wc -l || echo "0") + earthfile_count=$(($(git grep -i "earthly" -- "Earthfile" 2>/dev/null | wc -l || echo "0") + $(git grep -i "earthly" -- "*.earth" 2>/dev/null | wc -l || echo "0"))) + + echo "go_count=$go_count" >> $GITHUB_OUTPUT + echo "md_count=$md_count" >> $GITHUB_OUTPUT + echo "earthfile_count=$earthfile_count" >> $GITHUB_OUTPUT + + echo "PR branch - Total: $total_count (Go: $go_count, MD: $md_count, Earthfiles: $earthfile_count)" + + - name: Checkout main branch + run: | + git checkout origin/main + + - name: Count occurrences in main branch + id: count_main + run: | + # Count total occurrences + total_count=$(git grep -i "earthly" 2>/dev/null | wc -l || echo "0") + echo "main_total_count=$total_count" >> $GITHUB_OUTPUT + + # Count by file type + go_count=$(git grep -i "earthly" -- "*.go" 2>/dev/null | wc -l || echo "0") + md_count=$(git grep -i "earthly" -- "*.md" 2>/dev/null | wc -l || echo "0") + earthfile_count=$(($(git grep -i "earthly" -- "Earthfile" 2>/dev/null | wc -l || echo "0") + $(git grep -i "earthly" -- "*.earth" 2>/dev/null | wc -l || echo "0"))) + + echo "main_go_count=$go_count" >> $GITHUB_OUTPUT + echo "main_md_count=$md_count" >> $GITHUB_OUTPUT + echo "main_earthfile_count=$earthfile_count" >> $GITHUB_OUTPUT + + echo "Main branch - Total: $total_count (Go: $go_count, MD: $md_count, Earthfiles: $earthfile_count)" + + - name: Calculate difference + id: calculate + run: | + pr_count=${{ steps.count_pr.outputs.total_count }} + main_count=${{ steps.count_main.outputs.main_total_count }} + difference=$((main_count - pr_count)) + + # Calculate percentage with proper formatting + if [ $main_count -gt 0 ]; then + # Use awk for better decimal handling + percentage=$(awk "BEGIN {printf \"%.2f\", $difference * 100 / $main_count}") + else + percentage="0.00" + fi + + echo "difference=$difference" >> $GITHUB_OUTPUT + echo "percentage=$percentage" >> $GITHUB_OUTPUT + echo "pr_count=$pr_count" >> $GITHUB_OUTPUT + echo "main_count=$main_count" >> $GITHUB_OUTPUT + + # Calculate differences by type + go_diff=$((${{ steps.count_main.outputs.main_go_count }} - ${{ steps.count_pr.outputs.go_count }})) + md_diff=$((${{ steps.count_main.outputs.main_md_count }} - ${{ steps.count_pr.outputs.md_count }})) + earthfile_diff=$((${{ steps.count_main.outputs.main_earthfile_count }} - ${{ steps.count_pr.outputs.earthfile_count }})) + + echo "go_diff=$go_diff" >> $GITHUB_OUTPUT + echo "md_diff=$md_diff" >> $GITHUB_OUTPUT + echo "earthfile_diff=$earthfile_diff" >> $GITHUB_OUTPUT + + - name: Comment on PR + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0 + with: + script: | + const prCount = ${{ steps.calculate.outputs.pr_count }}; + const mainCount = ${{ steps.calculate.outputs.main_count }}; + const difference = ${{ steps.calculate.outputs.difference }}; + const percentage = '${{ steps.calculate.outputs.percentage }}'; + + // File type differences + const goDiff = ${{ steps.calculate.outputs.go_diff }}; + const mdDiff = ${{ steps.calculate.outputs.md_diff }}; + const earthfileDiff = ${{ steps.calculate.outputs.earthfile_diff }}; + + let emoji = '📊'; + let message = ''; + + if (difference > 0) { + emoji = '🎉'; + message = `Great progress! You've reduced "earthly" occurrences by **${difference}** (${percentage}%)`; + } else if (difference < 0) { + emoji = '⚠️'; + message = `Warning: "earthly" occurrences have increased by **${Math.abs(difference)}** (${Math.abs(parseFloat(percentage))}%)`; + } else { + emoji = '➖'; + message = 'No change in "earthly" occurrences'; + } + + // Build detailed breakdown + let breakdown = ''; + if (goDiff !== 0 || mdDiff !== 0 || earthfileDiff !== 0) { + breakdown = ` + + ### 📁 Changes by file type: + | File Type | Change | + |-----------|--------| + | Go files (.go) | ${goDiff > 0 ? '✅ -' + goDiff : goDiff < 0 ? '❌ +' + Math.abs(goDiff) : '➖ No change'} | + | Documentation (.md) | ${mdDiff > 0 ? '✅ -' + mdDiff : mdDiff < 0 ? '❌ +' + Math.abs(mdDiff) : '➖ No change'} | + | Earthfiles | ${earthfileDiff > 0 ? '✅ -' + earthfileDiff : earthfileDiff < 0 ? '❌ +' + Math.abs(earthfileDiff) : '➖ No change'} |`; + } + + const body = `## ${emoji} Are we earthbuild yet? + + ${message} + + ### 📈 Overall Progress + | Branch | Total Count | + |--------|-------------| + | main | ${mainCount} | + | This PR | ${prCount} | + | **Difference** | **${difference > 0 ? '-' : '+'}${Math.abs(difference)}** ${difference !== 0 ? `(${Math.abs(parseFloat(percentage))}%)` : ''} | + ${breakdown} + + --- + *Keep up the great work migrating from Earthly to Earthbuild!* 🚀 + +
+ 💡 Tips for finding more occurrences + + Run locally to see detailed breakdown: + \`\`\`bash + ./.github/scripts/count-earthly.sh + \`\`\` + + **Note that the goal is not to reach 0.** + There is anticipated to be at least _some_ occurences of \`earthly\` in the source code due to backwards compatibility with config files and language constructs. +
`; + + // Find existing comment + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + const botComment = comments.find(comment => + comment.user.type === 'Bot' && + comment.body.includes('Are we earthbuild yet?') + ); + + if (botComment) { + // Update existing comment + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body: body + }); + } else { + // Create new comment + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: body + }); + } From 833a5ab4ba138b1a1c0d708c7c423728ceaf80d1 Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Tue, 23 Sep 2025 16:28:40 +0100 Subject: [PATCH 2/5] chore: exclude earthly-count.yml --- .github/workflows/earthly-count.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/earthly-count.yml b/.github/workflows/earthly-count.yml index 8107b0bd4..cf4a5f00c 100644 --- a/.github/workflows/earthly-count.yml +++ b/.github/workflows/earthly-count.yml @@ -21,7 +21,7 @@ jobs: id: count_pr run: | # Count total occurrences - total_count=$(git grep -i "earthly" 2>/dev/null | wc -l || echo "0") + total_count=$(git grep -i "earthly" -- ':(exclude)earthly-count.yml' 2>/dev/null | wc -l || echo "0") echo "total_count=$total_count" >> $GITHUB_OUTPUT # Count by file type From 8f1687f18d8bfdeec88c39d234dee51be0927c7f Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Tue, 23 Sep 2025 16:32:02 +0100 Subject: [PATCH 3/5] chore: exclude earthly-count.yml --- .github/workflows/earthly-count.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/earthly-count.yml b/.github/workflows/earthly-count.yml index cf4a5f00c..3d0bf58db 100644 --- a/.github/workflows/earthly-count.yml +++ b/.github/workflows/earthly-count.yml @@ -21,7 +21,7 @@ jobs: id: count_pr run: | # Count total occurrences - total_count=$(git grep -i "earthly" -- ':(exclude)earthly-count.yml' 2>/dev/null | wc -l || echo "0") + total_count=$(git grep -i "earthly" -- ':!.github/workflows/earthly-count.yml' 2>/dev/null | wc -l || echo "0") echo "total_count=$total_count" >> $GITHUB_OUTPUT # Count by file type From 3bd6f40e3c1dcb6876fb1e8129c40188aaa7a3bf Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Tue, 23 Sep 2025 16:33:14 +0100 Subject: [PATCH 4/5] chore: exclude earthly-count.yml --- .github/workflows/earthly-count.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/earthly-count.yml b/.github/workflows/earthly-count.yml index 3d0bf58db..6c90e21f3 100644 --- a/.github/workflows/earthly-count.yml +++ b/.github/workflows/earthly-count.yml @@ -43,7 +43,7 @@ jobs: id: count_main run: | # Count total occurrences - total_count=$(git grep -i "earthly" 2>/dev/null | wc -l || echo "0") + total_count=$(git grep -i "earthly" -- ':!.github/workflows/earthly-count.yml' 2>/dev/null | wc -l || echo "0") echo "main_total_count=$total_count" >> $GITHUB_OUTPUT # Count by file type From cd32e83f5a59d9bd9857c8b6d77dd322258db269 Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Tue, 23 Sep 2025 17:05:34 +0100 Subject: [PATCH 5/5] chore: pass lint --- .github/workflows/earthly-count.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/earthly-count.yml b/.github/workflows/earthly-count.yml index 6c90e21f3..2bcdb68b3 100644 --- a/.github/workflows/earthly-count.yml +++ b/.github/workflows/earthly-count.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout PR branch - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 @@ -87,7 +87,7 @@ jobs: echo "earthfile_diff=$earthfile_diff" >> $GITHUB_OUTPUT - name: Comment on PR - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | const prCount = ${{ steps.calculate.outputs.pr_count }};