|
| 1 | +--- |
| 2 | +name: Manage Repository Labels |
| 3 | + |
| 4 | +'on': |
| 5 | + workflow_call: |
| 6 | + |
| 7 | +permissions: |
| 8 | + issues: write |
| 9 | + contents: read |
| 10 | + |
| 11 | +jobs: |
| 12 | + manage-labels: |
| 13 | + name: Create/Update Repository Labels |
| 14 | + runs-on: ubuntu-latest |
| 15 | + if: ${{ github.repository_owner == 'wp-cli' }} |
| 16 | + steps: |
| 17 | + - name: Check out source code |
| 18 | + uses: actions/checkout@v5 |
| 19 | + |
| 20 | + - name: Set up PHP environment |
| 21 | + uses: shivammathur/setup-php@v2 |
| 22 | + with: |
| 23 | + php-version: 'latest' |
| 24 | + env: |
| 25 | + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 26 | + |
| 27 | + - name: Check existence of composer.json file |
| 28 | + id: check_composer_file |
| 29 | + uses: andstor/file-existence-action@v3 |
| 30 | + with: |
| 31 | + files: "composer.json" |
| 32 | + |
| 33 | + - name: Get commands from composer.json |
| 34 | + id: get-commands |
| 35 | + if: steps.check_composer_file.outputs.files_exists == 'true' |
| 36 | + run: | |
| 37 | + # Extract commands from composer.json using composer config |
| 38 | + COMMANDS=$(composer config extra.commands 2>/dev/null || echo "[]") |
| 39 | + echo "commands=${COMMANDS}" >> "$GITHUB_OUTPUT" |
| 40 | + echo "Commands found: ${COMMANDS}" |
| 41 | +
|
| 42 | + - name: Create/Update labels |
| 43 | + uses: actions/github-script@v7 |
| 44 | + env: |
| 45 | + COMMANDS_JSON: ${{ steps.get-commands.outputs.commands }} |
| 46 | + with: |
| 47 | + script: | |
| 48 | + // Standard labels that should exist in every repository |
| 49 | + const standardLabels = [ |
| 50 | + { name: 'good-first-issue', color: '7057ff', description: 'Good for newcomers' }, |
| 51 | + { name: 'help-wanted', color: '008672', description: 'Extra attention is needed' }, |
| 52 | + { name: 'scope:documentation', color: 'FEF2C0', description: 'Related to documentation' }, |
| 53 | + { name: 'scope:testing', color: 'FEF2C0', description: 'Related to testing' }, |
| 54 | + { name: 'scope:distribution', color: '5B7E7E', description: 'Related to distribution' }, |
| 55 | + { name: 'status:unconfirmed', color: 'BFE5BF', description: 'Issue was could not be confirmed yet' }, |
| 56 | + { name: 'status:unsupported', color: 'BFE5BF', description: 'Ask is not supported' } |
| 57 | + ]; |
| 58 | +
|
| 59 | + // Parse commands from composer.json |
| 60 | + const commandsEnv = process.env.COMMANDS_JSON || '[]'; |
| 61 | + let commands = []; |
| 62 | + |
| 63 | + try { |
| 64 | + commands = JSON.parse(commandsEnv); |
| 65 | + if (!Array.isArray(commands)) { |
| 66 | + commands = []; |
| 67 | + } |
| 68 | + } catch (e) { |
| 69 | + console.log('No commands found or invalid JSON format'); |
| 70 | + commands = []; |
| 71 | + } |
| 72 | +
|
| 73 | + // Generate command-specific labels |
| 74 | + const commandLabels = commands.map(command => { |
| 75 | + // Convert command to label format: replace spaces with dashes |
| 76 | + const labelName = 'command:' + command.replace(/\s+/g, '-'); |
| 77 | + return { |
| 78 | + name: labelName, |
| 79 | + color: 'C5DEF5', |
| 80 | + description: `Related to '${command}' command` |
| 81 | + }; |
| 82 | + }); |
| 83 | +
|
| 84 | + // Combine all labels |
| 85 | + const allLabels = [...standardLabels, ...commandLabels]; |
| 86 | +
|
| 87 | + console.log(`Creating/updating ${allLabels.length} labels...`); |
| 88 | +
|
| 89 | + // Create or update each label |
| 90 | + for (const label of allLabels) { |
| 91 | + try { |
| 92 | + // Try to get existing label |
| 93 | + try { |
| 94 | + await github.rest.issues.getLabel({ |
| 95 | + owner: context.repo.owner, |
| 96 | + repo: context.repo.repo, |
| 97 | + name: label.name |
| 98 | + }); |
| 99 | + |
| 100 | + // Update if it exists |
| 101 | + await github.rest.issues.updateLabel({ |
| 102 | + owner: context.repo.owner, |
| 103 | + repo: context.repo.repo, |
| 104 | + name: label.name, |
| 105 | + color: label.color, |
| 106 | + description: label.description |
| 107 | + }); |
| 108 | + console.log(`✓ Updated label: ${label.name}`); |
| 109 | + } catch (error) { |
| 110 | + if (error.status === 404) { |
| 111 | + // Create if it doesn't exist |
| 112 | + await github.rest.issues.createLabel({ |
| 113 | + owner: context.repo.owner, |
| 114 | + repo: context.repo.repo, |
| 115 | + name: label.name, |
| 116 | + color: label.color, |
| 117 | + description: label.description |
| 118 | + }); |
| 119 | + console.log(`✓ Created label: ${label.name}`); |
| 120 | + } else { |
| 121 | + throw error; |
| 122 | + } |
| 123 | + } |
| 124 | + } catch (error) { |
| 125 | + console.error(`✗ Failed to process label '${label.name}': ${error.message}`); |
| 126 | + } |
| 127 | + } |
| 128 | +
|
| 129 | + console.log('Label management complete!'); |
0 commit comments