Skip to content

Rebuild Metadata (Bot Action) #751

Rebuild Metadata (Bot Action)

Rebuild Metadata (Bot Action) #751

name: Rebuild Metadata (Bot Action)
on:
issue_comment:
types: [created]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to rebuild metadata for'
required: true
jobs:
rebuild-metadata:
if: |
github.event_name == 'workflow_dispatch' ||
(github.event.issue.pull_request && contains(github.event.comment.body, '/bot rebuild-metadata'))
runs-on: ubuntu-latest-8-core-x64
permissions:
contents: write
pull-requests: write
steps:
- name: Check user permission
if: github.event_name == 'issue_comment'
id: check_permission
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const association = context.payload.comment.author_association;
if (!['MEMBER', 'OWNER'].includes(association)) {
core.setFailed(`User ${context.actor} is not an org member or owner (association: ${association})`);
return;
}
const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.actor
});
const allowed = ['admin', 'write'].includes(permission.permission);
if (!allowed) {
core.setFailed(`User ${context.actor} does not have write permission`);
}
- name: Add reaction to comment
if: github.event_name == 'issue_comment'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'rocket'
})
- name: Get PR branch
id: pr
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
PR_NUMBER: ${{ github.event.inputs.pr_number }}
with:
script: |
const prNumber = context.eventName === 'workflow_dispatch'
? process.env.PR_NUMBER
: context.issue.number;
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
if (pr.data.head.repo === null || pr.data.head.repo.fork) {
core.setFailed('Bot commands are not allowed on fork PRs for security reasons');
return;
}
core.setOutput('ref', pr.data.head.ref);
core.setOutput('sha', pr.data.head.sha);
core.setOutput('number', prNumber);
- name: Checkout PR branch
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: true
ref: ${{ steps.pr.outputs.sha }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup Earthly
uses: EarthBuild/actions-setup@cae2d9ab68894d8402751fe42e07c7cca0272f7f
with:
version: v0.8.16
github-token: ${{ github.token }}
use-cache: false
- name: Login to GHCR
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
- name: Run rebuild-metadata
env:
EARTHLY_CONFIG: .earthly/config.yml
run: |
mkdir -p "$HOME"/.cargo
echo "[net]" >> "$HOME"/.cargo/config
echo "git-fetch-with-cli = true" >> "$HOME"/.cargo/config
earthly -P +rebuild-metadata
- name: Commit and push changes
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
id: commit
with:
script: |
const fs = require('fs');
const path = require('path');
// Check if there are changes
const { execSync } = require('child_process');
const status = execSync('git status --porcelain').toString();
if (!status.trim()) {
core.exportVariable('CHANGES_MADE', 'false');
console.log('No changes to commit');
return;
}
// Get changed files in metadata/static/
const changedFiles = status.split('\n')
.filter(line => line.trim())
.map(line => line.substring(3))
.filter(file => file.startsWith('metadata/static/'));
if (changedFiles.length === 0) {
core.exportVariable('CHANGES_MADE', 'false');
console.log('No metadata changes to commit');
return;
}
// Prepare file additions
const additions = changedFiles.map(filePath => {
const contents = fs.readFileSync(filePath);
return {
path: filePath,
contents: contents.toString('base64')
};
});
// Get current HEAD
const headOid = execSync('git rev-parse HEAD').toString().trim();
// Create commit via GraphQL API
const result = await github.graphql(`
mutation($input: CreateCommitOnBranchInput!) {
createCommitOnBranch(input: $input) {
commit {
oid
}
}
}
`, {
input: {
branch: {
repositoryNameWithOwner: '${{ github.repository }}',
branchName: '${{ steps.pr.outputs.ref }}'
},
message: {
headline: 'chore: rebuild metadata'
},
expectedHeadOid: headOid,
fileChanges: {
additions: additions
}
}
});
console.log('Commit created:', result.createCommitOnBranch.commit.oid);
core.exportVariable('CHANGES_MADE', 'true');
- name: Post success comment
if: env.CHANGES_MADE == 'true'
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
with:
message: |
:white_check_mark: Metadata rebuild complete! Changes have been committed.
pr-number: ${{ steps.pr.outputs.number }}
- name: Post no-changes comment
if: env.CHANGES_MADE == 'false'
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
with:
message: |
:white_check_mark: Metadata rebuild complete. No changes detected.
pr-number: ${{ steps.pr.outputs.number }}
- name: Post failure comment
if: failure()
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
with:
message: |
:x: Metadata rebuild failed. Check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
pr-number: ${{ steps.pr.outputs.number }}