[BUILD REQUEST] waterfox-bin - shasum mismatch error #8
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: 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 }} |