zod-engine: init #257
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: PR Bot | |
| on: | |
| issue_comment: | |
| types: [created] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| actions: write | |
| attestations: write | |
| id-token: write | |
| packages: write | |
| jobs: | |
| handle-command: | |
| # Only run on PR comments (not issue comments) and from authorized users | |
| if: | | |
| github.event.issue.pull_request && | |
| startsWith(github.event.comment.body, '/') && | |
| ( | |
| github.event.comment.author_association == 'OWNER' || | |
| github.event.comment.author_association == 'MEMBER' || | |
| github.event.comment.author_association == 'COLLABORATOR' | |
| ) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Get PR info | |
| id: pr-info | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| PR_DATA=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }}) | |
| echo "head_sha=$(echo "$PR_DATA" | jq -r '.head.sha')" >> $GITHUB_OUTPUT | |
| echo "head_ref=$(echo "$PR_DATA" | jq -r '.head.ref')" >> $GITHUB_OUTPUT | |
| echo "base_ref=$(echo "$PR_DATA" | jq -r '.base.ref')" >> $GITHUB_OUTPUT | |
| - name: Parse command | |
| id: parse | |
| run: | | |
| COMMENT="${{ github.event.comment.body }}" | |
| COMMAND=$(echo "$COMMENT" | head -1 | awk '{print $1}' | tr -d '/') | |
| ARGS=$(echo "$COMMENT" | head -1 | cut -d' ' -f2- -s) | |
| echo "command=$COMMAND" >> $GITHUB_OUTPUT | |
| echo "args=$ARGS" >> $GITHUB_OUTPUT | |
| echo "Parsed command: $COMMAND, args: $ARGS" | |
| - name: React to comment | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ | |
| -f content='eyes' || true | |
| - name: Handle /help | |
| if: steps.parse.outputs.command == 'help' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| HELP_MSG=$(cat << 'EOF' | |
| ## π€ PR Bot Commands | |
| | Command | Description | | |
| |---------|-------------| | |
| | `/help` | Show this help message | | |
| | `/validate` | Validate the package tree | | |
| | `/check` | Check upstream versions | | |
| | `/approve` | Approve and merge (maintainers only) | | |
| <sub>Commands are only available to repository collaborators.</sub> | |
| EOF | |
| ) | |
| gh pr comment ${{ github.event.issue.number }} \ | |
| --repo ${{ github.repository }} \ | |
| --body "$HELP_MSG" | |
| - name: Checkout for validate | |
| if: steps.parse.outputs.command == 'validate' | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Handle /validate | |
| if: steps.parse.outputs.command == 'validate' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| PR_NUM="${{ github.event.issue.number }}" | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "π **Validating package tree...**" | |
| gh pr checkout "$PR_NUM" | |
| curl -fsSL "https://github.com/pkgforge/sbuilder/releases/download/nightly/sbuild-x86_64-linux" \ | |
| -o /tmp/sbuild && chmod +x /tmp/sbuild | |
| # The validator checks the whole tree at once; it needs no network | |
| # and one package can invalidate another, so there is no subset to | |
| # usefully check. | |
| if /tmp/sbuild validate > /tmp/validate.txt 2>&1; then | |
| EMOJI="β "; STATUS="Validation Passed" | |
| else | |
| EMOJI="β"; STATUS="Validation Failed" | |
| fi | |
| OUTPUT=$(head -40 /tmp/validate.txt) | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "## ${EMOJI} ${STATUS} | |
| \`\`\` | |
| ${OUTPUT} | |
| \`\`\` | |
| <sub>Triggered by @${{ github.event.comment.user.login }}</sub>" | |
| - name: Checkout for check | |
| if: steps.parse.outputs.command == 'check' | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Handle /check | |
| if: steps.parse.outputs.command == 'check' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| PR_NUM="${{ github.event.issue.number }}" | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "π **Checking upstream versions...**" | |
| # Checkout PR branch | |
| gh pr checkout "$PR_NUM" | |
| # Download sbuild | |
| curl -fsSL "https://github.com/pkgforge/sbuilder/releases/download/nightly/sbuild-x86_64-linux" \ | |
| -o /tmp/sbuild && chmod +x /tmp/sbuild || { | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "β οΈ Failed to download sbuild" | |
| exit 1 | |
| } | |
| # Run version check | |
| /tmp/sbuild resolve . \ | |
| --recipes ./binaries ./packages \ | |
| --output /tmp/updates.json \ | |
| --parallel 5 \ | |
| --timeout 30 || true | |
| if [ ! -f /tmp/updates.json ] || [ "$(jq 'length' /tmp/updates.json)" = "0" ]; then | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "β **Version check complete** - All packages are up to date!" | |
| exit 0 | |
| fi | |
| # Format results | |
| RESULTS="| Package | Current | Upstream | | |
| |---------|---------|----------|" | |
| while read -r line; do | |
| pkg=$(echo "$line" | jq -r '.pkg') | |
| current=$(echo "$line" | jq -r '.current_version') | |
| upstream=$(echo "$line" | jq -r '.upstream_version') | |
| RESULTS="${RESULTS} | |
| | \`${pkg}\` | ${current} | **${upstream}** |" | |
| done < <(jq -c '.[]' /tmp/updates.json) | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "## π¦ Version Check Results | |
| ${RESULTS} | |
| <sub>Triggered by @${{ github.event.comment.user.login }}</sub>" | |
| - name: Handle /approve | |
| if: steps.parse.outputs.command == 'approve' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| PR_NUM="${{ github.event.issue.number }}" | |
| USER="${{ github.event.comment.user.login }}" | |
| ASSOC="${{ github.event.comment.author_association }}" | |
| # Only owners/admins can approve | |
| if [[ "$ASSOC" != "OWNER" && "$ASSOC" != "MEMBER" ]]; then | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "β οΈ @${USER} Only repository owners/members can use \`/approve\`" | |
| exit 0 | |
| fi | |
| # Approve the PR | |
| gh pr review "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --approve \ | |
| --body "β Approved via \`/approve\` command by @${USER}" | |
| gh pr comment "$PR_NUM" \ | |
| --repo ${{ github.repository }} \ | |
| --body "β **PR Approved** by @${USER} | |
| Ready to merge when checks pass." | |
| - name: Handle unknown command | |
| if: | | |
| steps.parse.outputs.command != 'help' && | |
| steps.parse.outputs.command != 'build' && | |
| steps.parse.outputs.command != 'lint' && | |
| steps.parse.outputs.command != 'check' && | |
| steps.parse.outputs.command != 'approve' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| COMMAND="${{ steps.parse.outputs.command }}" | |
| gh pr comment ${{ github.event.issue.number }} \ | |
| --repo ${{ github.repository }} \ | |
| --body "β Unknown command: \`/${COMMAND}\` | |
| Use \`/help\` to see available commands." |