Skip to content

[BUILD REQUEST] waterfox-bin - shasum mismatch error #8

[BUILD REQUEST] waterfox-bin - shasum mismatch error

[BUILD REQUEST] waterfox-bin - shasum mismatch error #8

name: Issue Triggered Build
on:
issues:
types: [opened]
jobs:
parse-and-build:
runs-on: ubuntu-latest
steps:
- name: Parse issue body and update title
id: parse
uses: actions/github-script@v7
with:
script: |
const issueBody = context.payload.issue.body || '';
console.log('Issue body:', issueBody);
// Parse and validate the package name
let packageName = 'waterfox-bin'; // default
const packageMatch = issueBody.match(/### Package to Build\s*\n\s*([^\n]+)/);
if (packageMatch) {
packageName = packageMatch[1].trim();
}
// Check for custom package name
const customMatch = issueBody.match(/### Custom Package Name\s*\n\s*([^\n]+)/);
if (packageName === 'custom-package' && customMatch && customMatch[1].trim() !== '*No response*') {
packageName = customMatch[1].trim();
}
// Validate package name
const packageValidationErrors = [];
// Package name validation
if (packageName.length > 100) {
packageValidationErrors.push('Package name too long (max 100 characters)');
}
// Only allow package-name-like format
const validPackageName = /^[a-zA-Z0-9\-_.+]+$/;
if (!validPackageName.test(packageName)) {
packageValidationErrors.push('Package name contains invalid characters (only a-z, A-Z, 0-9, -, _, ., + allowed)');
}
// Prevent path traversal
if (packageName.includes('..') || packageName.includes('/') || packageName.includes('\\')) {
packageValidationErrors.push('Package name cannot contain path separators or traversal sequences');
}
if (packageValidationErrors.length > 0) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `❌ **Build Request Rejected**\n\nPackage name validation errors:\n${packageValidationErrors.map(err => `- ${err}`).join('\n')}\n\nPlease create a new issue with a valid package name.`
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
state: 'closed',
labels: ['invalid', 'security-rejected']
});
core.setFailed('Build request rejected due to package name validation errors');
return;
}
// Parse the reason with validation
let reason = 'Build requested';
const reasonMatch = issueBody.match(/### Reason for Build\s*\n\s*([^\n]+)/);
if (reasonMatch && reasonMatch[1].trim() !== '*No response*') {
let rawReason = reasonMatch[1].trim();
// Security validation for the reason field
const validationErrors = [];
// Length validation
if (rawReason.length > 200) {
validationErrors.push('Reason too long (max 200 characters)');
}
// Character whitelist - alphanumerics and safe punctuation only
const allowedChars = /^[a-zA-Z0-9\s\-_.,!?():;'"@#%&+=[\]{}\/\\*]+$/;
if (!allowedChars.test(rawReason)) {
validationErrors.push('Reason contains invalid characters');
}
// Block dangerous shell metacharacters and control sequences
const dangerousPatterns = [
/[`|<>$]/, // Shell metacharacters (backticks, pipes, redirections, variables)
/\r|\n/, // Line breaks
/\x00-\x1F/, // Control characters (except space)
/\x7F/, // DEL character
];
for (const pattern of dangerousPatterns) {
if (pattern.test(rawReason)) {
validationErrors.push('Reason contains potentially dangerous characters');
break;
}
}
if (validationErrors.length > 0) {
// Post validation errors and exit
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `❌ **Build Request Rejected**\n\nValidation errors:\n${validationErrors.map(err => `- ${err}`).join('\n')}\n\nPlease create a new issue with a valid reason.`
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
state: 'closed',
labels: ['invalid', 'security-rejected']
});
core.setFailed('Build request rejected due to validation errors');
return;
}
reason = rawReason;
}
// Update the issue title
const newTitle = `[BUILD REQUEST] ${packageName} - ${reason}`;
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
title: newTitle
});
// Format as JSON array string for the manual build workflow
const packagesJson = `["${packageName}"]`;
console.log('Parsed package:', packageName);
console.log('Reason:', reason);
console.log('Updated title to:', newTitle);
console.log('Packages JSON:', packagesJson);
core.setOutput('packages_json', packagesJson);
core.setOutput('package_name', packageName);
core.setOutput('reason', reason);
- name: Add reaction to issue
uses: actions/github-script@v7
with:
script: |
github.rest.reactions.createForIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
content: 'rocket'
});
- name: Comment on issue
uses: actions/github-script@v7
with:
script: |
const packageName = '${{ steps.parse.outputs.package_name }}';
const reason = '${{ steps.parse.outputs.reason }}';
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `🚀 Build request received for package: **${packageName}**\nReason: ${reason}\n\nTriggering build workflow...`
});
- name: Trigger manual build workflow
uses: actions/github-script@v7
with:
script: |
const packagesJson = '${{ steps.parse.outputs.packages_json }}';
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'manual_build.yml',
ref: 'main',
inputs: {
packages_json: packagesJson,
build_mode: 'build'
}
});
console.log(`Triggered manual_build.yml with packages_json: ${packagesJson}`);
- name: Update issue with build status
uses: actions/github-script@v7
with:
script: |
const packageName = '${{ steps.parse.outputs.package_name }}';
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `✅ Build workflow triggered successfully for **${packageName}**\n\nYou can monitor the build progress in the [Actions tab](https://github.com/${context.repo.owner}/${context.repo.repo}/actions).`
});
// Close the issue since the build has been triggered
github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
state: 'closed'
});
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}