feat: example for ffufai #39
Workflow file for this run
This file contains 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: Validate Contributions | |
on: | |
pull_request: | |
paths: | |
- '**.yml' | |
- '!.github/**' | |
branches: | |
- main | |
jobs: | |
validate: | |
runs-on: ubuntu-latest | |
permissions: | |
pull-requests: write | |
contents: read | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 | |
with: | |
fetch-depth: 0 # Fetch all history | |
ref: ${{ github.head_ref }} # Checkout the PR branch | |
- name: Set up Docker | |
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # 3.7.1 | |
- name: Validate Contribution Files | |
id: robopages-validation | |
run: | | |
validate_file() { | |
local file="$1" | |
local tmp_file="/tmp/$(basename $file)" | |
local validation_status=0 | |
if [[ ! "$file" =~ ^([a-zA-Z0-9_\-]+/)*[a-zA-Z0-9_\-]+\.yml$ ]]; then | |
echo "Invalid file path characters: $file" | |
return 1 | |
fi | |
if [[ "$file" == *"../"* ]]; then | |
echo "Directory traversal attempt detected: $file" | |
return 1 | |
fi | |
# Create copy and inject categories if missing | |
cp "$file" "$tmp_file" | |
if ! grep -q "categories:" "$tmp_file"; then | |
# Extract categories from path | |
categories=$(dirname "$file" | tr '/' '\n' | awk 'NF' | sed 's/^/ - /') | |
# Inject categories into YAML | |
echo -e "\ncategories:\n$categories" >> "$tmp_file" | |
fi | |
docker pull dreadnode/robopages:latest | |
# Run validation and capture the exit status | |
docker run --rm \ | |
-v $(pwd):/workspace \ | |
-v /var/run/docker.sock:/var/run/docker.sock \ | |
-v "$tmp_file:/workspace/$(basename $file)" \ | |
-w /workspace \ | |
--privileged \ | |
dreadnode/robopages:latest validate --path "$(basename $file)" --skip-docker || validation_status=$? | |
rm "$tmp_file" | |
return $validation_status | |
} | |
# Initialize overall status | |
overall_status=0 | |
# Get changed files using GitHub's provided variables | |
changed_files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} | \ | |
grep '\.yml$' | grep -v '^.github/' || true) | |
# Validate each changed file | |
for file in $changed_files; do | |
echo "Validating $file..." | |
if ! validate_file "$file"; then | |
overall_status=1 | |
echo "::error::Validation failed for $file" | |
fi | |
done | |
exit $overall_status | |
- name: Post validation status | |
if: always() | |
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #7.0.1 | |
with: | |
script: | | |
const validation_status = process.env.STATE_validation === '0' | |
? '✅ Validation successful' | |
: '❌ Validation failed'; | |
const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; | |
const timestamp = new Date().toISOString(); | |
const body = [ | |
`## Validation Results (${timestamp})`, | |
'', | |
validation_status, | |
'', | |
'Please ensure your contribution follows the required format.', | |
'', | |
`[View Full Validation Details](${runUrl})`, | |
'', | |
'---', | |
`Run ID: \`${process.env.GITHUB_RUN_ID}\``, | |
`Workflow: ${process.env.GITHUB_WORKFLOW}` | |
].join('\n'); | |
github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
body: body | |
}); |