Skip to content

Command

Command #14

Workflow file for this run

name: Command
on:
issue_comment: # listen for comments on issues
types: [ created ]
permissions: # allow the action to comment on the PR
contents: write
issues: write
pull-requests: write
actions: read
jobs:
is-org-member:
if: startsWith(github.event.comment.body, '/cmd')
runs-on: ubuntu-latest
outputs:
member: ${{ steps.is-member.outputs.is-member }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate token
id: generate_token
uses: tibdex/github-app-token@v2.1.0
with:
app_id: ${{ secrets.CMD_BOT_APP_ID }}
private_key: ${{ secrets.CMD_BOT_APP_KEY }}
- name: Check if user is a member of the organization
id: is-member
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
const fs = require("fs");
try {
const org = '${{ github.event.repository.owner.login }}';
const username = '${{ github.event.comment.user.login }}';
const membership = await github.rest.orgs.checkMembershipForUser({
org: org,
username: username
});
console.log(membership, membership.status, membership.status === 204);
if (membership.status === 204) {
return 'true';
} else {
console.log(membership);
fs.appendFileSync(process.env["GITHUB_STEP_SUMMARY"], `${membership.data && membership.data.message || 'Unknown error happened, please check logs'}`);
}
} catch (error) {
console.log(error)
}
return 'false';
test:
runs-on: ubuntu-latest
needs: is-org-member
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Test
run: |
echo "${{ needs.is-org-member.outputs.member }}"
reject-non-members:
needs: is-org-member
if: ${{ startsWith(github.event.comment.body, '/cmd') && needs.is-org-member.outputs.member != 'true' }}
runs-on: ubuntu-latest
steps:
- name: Add reaction to rejected comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.reactions.createForIssueComment({
comment_id: ${{ github.event.comment.id }},
owner: context.repo.owner,
repo: context.repo.repo,
content: 'confused'
})
- name: Comment PR (Rejected)
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Sorry, only ${{ github.event.repository.owner.login }} members can run commands.`
})
acknowledge:
needs: is-org-member
if: ${{ startsWith(github.event.comment.body, '/cmd') && needs.is-org-member.outputs.member == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Add reaction to triggered comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.reactions.createForIssueComment({
comment_id: ${{ github.event.comment.id }},
owner: context.repo.owner,
repo: context.repo.repo,
content: 'eyes'
})
clean:
needs: is-org-member
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Clean previous comments
if: ${{ startsWith(github.event.comment.body, '/cmd') && contains(github.event.comment.body, '--clean') && needs.is-org-member.outputs.member == 'true' }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
}).then(comments => {
for (let comment of comments.data) {
console.log(comment)
if (
${{ github.event.comment.id }} !== comment.id &&
(
((comment.body.startsWith('Command') || comment.body.startsWith('<details><summary>Command')) && comment.user.type === 'Bot') ||
(comment.body.startsWith('/cmd') && comment.user.login === context.actor)
)
) {
github.rest.issues.deleteComment({
comment_id: comment.id,
owner: context.repo.owner,
repo: context.repo.repo
})
}
}
})
help:
needs: [ clean, is-org-member ]
if: ${{ startsWith(github.event.comment.body, '/cmd') && contains(github.event.comment.body, '--help') && needs.is-org-member.outputs.member == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get command
uses: actions-ecosystem/action-regex-match@v2
id: get-pr-comment
with:
text: ${{ github.event.comment.body }}
regex: '^(\/cmd )([\s\w-]+)$'
- name: Save output of help
id: help
env:
CMD: ${{ steps.get-pr-comment.outputs.group2 }} # to avoid "" around the command
run: |
echo 'help<<EOF' >> $GITHUB_OUTPUT
python3 .github/scripts/cmd/cmd.py $CMD >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- name: Comment PR (Help)
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `<details><summary>Command help:</summary>${{ steps.help.outputs.help }}</details>`
})
- name: Add confused reaction on failure
uses: actions/github-script@v7
if: ${{ failure() }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.reactions.createForIssueComment({
comment_id: ${{ github.event.comment.id }},
owner: context.repo.owner,
repo: context.repo.repo,
content: 'confused'
})
- name: Add πŸ‘ reaction on success
uses: actions/github-script@v7
if: ${{ !failure() }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.reactions.createForIssueComment({
comment_id: ${{ github.event.comment.id }},
owner: context.repo.owner,
repo: context.repo.repo,
content: '+1'
})
cmd:
needs: [ clean, is-org-member ]
env:
JOB_NAME: 'cmd'
if: ${{ startsWith(github.event.comment.body, '/cmd') && !contains(github.event.comment.body, '--help') && needs.is-org-member.outputs.member == 'true' }}
runs-on: ${{ startsWith(github.event.comment.body, '/cmd bench') && 'arc-runners-polkadot-sdk-benchmark' || 'ubuntu-latest' }}
steps:
- name: Install updates and protobuf-compiler
if: startsWith(github.event.comment.body, '/cmd bench')
run: |
sudo apt update && sudo apt install --assume-yes \
openssl pkg-config g++ make cmake protobuf-compiler curl libssl-dev libclang-dev libudev-dev git jq
- name: Get command
uses: actions-ecosystem/action-regex-match@v2
id: get-pr-comment
with:
text: ${{ github.event.comment.body }}
regex: '^(\/cmd )([\s\w-]+)$'
- name: Build workflow link
if: ${{ !contains(github.event.comment.body, '--quiet') }}
id: build-link
run: |
# Get exactly the CMD job link, filtering out the other jobs
jobLink=$(curl -s \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs | jq '.jobs[] | select(.name | contains("${{ env.JOB_NAME }}")) | .html_url')
runLink=$(curl -s \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }} | jq '.html_url')
echo "job_url=${jobLink}"
echo "run_url=${runLink}"
echo "job_url=$jobLink" >> $GITHUB_OUTPUT
echo "run_url=$runLink" >> $GITHUB_OUTPUT
- name: Comment PR (Start)
if: ${{ !contains(github.event.comment.body, '--quiet') }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
let job_url = ${{ steps.build-link.outputs.job_url }}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Command "${{ steps.get-pr-comment.outputs.group2 }}" has started πŸš€ [See logs here](${job_url})`
})
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Set rust version via common env file
run: cat .github/env >> $GITHUB_ENV
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
targets: "wasm32-unknown-unknown,x86_64-unknown-linux-musl"
components: "rust-src rustfmt clippy"
toolchain: "nightly-${{env.RUST_NIGHTLY_VERSION}}"
- name: Install dependencies for bench
if: startsWith(steps.get-pr-comment.outputs.group2, 'bench')
run: cargo install subweight frame-omni-bencher --locked
- name: Install dependencies for fmt
if: startsWith(steps.get-pr-comment.outputs.group2, 'fmt')
run: cargo install taplo-cli --version ${{ env.TAPLO_VERSION }}
- name: Setup Cache
if: startsWith(steps.get-pr-comment.outputs.group2, 'bench')
uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2.7.0
with:
shared-key: "polkadot-sdk-cmd-${{ github.sha }}"
- name: Run cmd
id: cmd
env:
CMD: ${{ steps.get-pr-comment.outputs.group2 }} # to avoid "" around the command
run: |
echo "Running command: $CMD"
git remote -v
python3 .github/scripts/cmd/cmd.py $CMD
git status
git diff
- name: Commit changes
run: |
if [ -n "$(git status --porcelain)" ]; then
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git pull origin ${{ github.head_ref }}
git add .
git restore --staged Cargo.lock # ignore changes in Cargo.lock
git commit -m "Update from ${{ github.actor }} running command '${{ steps.get-pr-comment.outputs.group2 }}'" || true
git push origin ${{ github.head_ref }}
else
echo "Nothing to commit";
fi
- name: Run Subweight
id: subweight
if: startsWith(steps.get-pr-comment.outputs.group2, 'bench')
shell: bash
run: |
git fetch
result=$(subweight compare commits \
--path-pattern "./**/weights/**/*.rs" \
--method asymptotic \
--format markdown \
--no-color \
--change added changed \
--ignore-errors \
refs/remotes/origin/main ${{ github.ref }})
# Save the multiline result to the output
{
echo "result<<EOF"
echo "$result"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Comment PR (End)
if: ${{ !failure() && !contains(github.event.comment.body, '--quiet') }}
uses: actions/github-script@v7
env:
SUBWEIGHT: '${{ steps.subweight.outputs.result }}'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
let runUrl = ${{ steps.build-link.outputs.run_url }}
let subweight = process.env.SUBWEIGHT;
let subweightCollapsed = subweight
? `<details>\n\n<summary>Subweight results:</summary>\n\n${subweight}\n\n</details>`
: '';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Command "${{ steps.get-pr-comment.outputs.group2 }}" has finished βœ… [See logs here](${runUrl})${subweightCollapsed}`
})
- name: Comment PR (Failure)
if: ${{ failure() && !contains(github.event.comment.body, '--quiet') }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
let jobUrl = ${{ steps.build-link.outputs.job_url }}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Command "${{ steps.get-pr-comment.outputs.group2 }}" has failed ❌! [See logs here](${jobUrl})`
})
- name: Add πŸ˜• reaction on failure
uses: actions/github-script@v7
if: ${{ failure() }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.reactions.createForIssueComment({
comment_id: ${{ github.event.comment.id }},
owner: context.repo.owner,
repo: context.repo.repo,
content: 'confused'
})
- name: Add πŸ‘ reaction on success
uses: actions/github-script@v7
if: ${{ !failure() }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.reactions.createForIssueComment({
comment_id: ${{ github.event.comment.id }},
owner: context.repo.owner,
repo: context.repo.repo,
content: '+1'
})