name: 📝 Artifact Comment on PR concurrency: group: artifact-comment-${{ github.event.workflow_run.head_branch }} cancel-in-progress: true on: workflow_run: workflows: ["🤖 iOS IPA Build (Phone + TV)", "🤖 Android APK Build (Phone + TV)"] types: - completed jobs: comment-artifacts: if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest permissions: contents: read pull-requests: write actions: read steps: - name: 🔍 Get PR and Artifacts uses: actions/github-script@v8 with: script: | // Find PR associated with this commit const { data: pullRequests } = await github.rest.repos.listPullRequestsAssociatedWithCommit({ owner: context.repo.owner, repo: context.repo.repo, commit_sha: "${{ github.event.workflow_run.head_sha }}" }); if (pullRequests.length === 0) { core.setFailed('No pull request found for this commit'); return; } const pr = pullRequests[0]; const runId = "${{ github.event.workflow_run.id }}"; // Get artifacts from the workflow run const { data: artifacts } = await github.rest.actions.listWorkflowRunArtifacts({ owner: context.repo.owner, repo: context.repo.repo, run_id: runId }); if (artifacts.artifacts.length === 0) { console.log('No artifacts found for this run'); return; } // Sort and categorize artifacts const androidArtifacts = artifacts.artifacts .filter(a => a.name.includes('android')) .sort((a, b) => a.name.localeCompare(b.name)); const iosArtifacts = artifacts.artifacts .filter(a => a.name.includes('ios')) .sort((a, b) => a.name.localeCompare(b.name)); // Build comment body with table format let commentBody = `## 📱 Build Artifacts Ready!\n\n`; commentBody += `✅ **Workflow completed successfully** for PR #${pr.number}\n`; commentBody += `📦 **${artifacts.artifacts.length} artifacts** generated from commit [\`${pr.head.sha.substring(0, 7)}\`](https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${pr.head.sha})\n\n`; // Create table for better organization commentBody += `| Platform | Device Type | Download Link |\n`; commentBody += `|----------|-------------|---------------|\n`; // Add Android artifacts androidArtifacts.forEach(artifact => { const isTV = artifact.name.includes('tv'); const deviceType = isTV ? '📺 Android TV' : '📱 Android Phone'; const nightlyLink = `https://nightly.link/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}/${artifact.name}.zip`; commentBody += `| 🤖 Android | ${deviceType} | [📥 Download APK](${nightlyLink}) |\n`; }); // Add iOS artifacts iosArtifacts.forEach(artifact => { const isTV = artifact.name.includes('tv'); const deviceType = isTV ? '📺 Apple TV' : '📱 iPhone/iPad'; const nightlyLink = `https://nightly.link/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}/${artifact.name}.zip`; commentBody += `| 🍎 iOS | ${deviceType} | [📥 Download IPA](${nightlyLink}) |\n`; }); commentBody += `\n`; commentBody += `### 🔧 Installation Instructions\n\n`; commentBody += `- **Android APK**: Download and install directly on your device (enable "Install from unknown sources")\n`; commentBody += `- **iOS IPA**: Install using [AltStore](https://altstore.io/), [Sideloadly](https://sideloadly.io/), or Xcode\n\n`; commentBody += `> ⚠️ **Note**: Artifacts expire in 7 days from build date\n\n`; commentBody += `*Auto-generated by [GitHub Actions](${context.payload.workflow_run.html_url})*`; // Find existing bot comment to update const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr.number }); const botComment = comments.find(comment => comment.user.type === 'Bot' && comment.body.includes('Build Artifacts Ready!') ); if (botComment) { // Update existing comment await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: botComment.id, body: commentBody }); console.log(`✅ Updated comment ${botComment.id} on PR #${pr.number}`); } else { // Create new comment await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr.number, body: commentBody }); console.log(`✅ Created new comment on PR #${pr.number}`); }