Create team: TEAM-KLP #45
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: Create Team | |
| on: | |
| pull_request: | |
| types: [closed] | |
| paths: | |
| - 'team-name.txt' | |
| branches: [main] | |
| permissions: | |
| contents: write | |
| jobs: | |
| create_team: | |
| if: github.event.pull_request.merged == true | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Extract Team Details | |
| id: extract | |
| run: | | |
| if [ ! -f team-name.txt ]; then | |
| echo "::error::team-name.txt not found!" | |
| exit 1 | |
| fi | |
| TEAM_NAME=$(cat team-name.txt | sed 's/[`]//g' | xargs) | |
| if [[ ! "$TEAM_NAME" =~ ^TEAM-[a-zA-Z0-9_-]+$ ]]; then | |
| echo "::error::Invalid team name format: '$TEAM_NAME'" | |
| exit 1 | |
| fi | |
| PR_BODY=$(echo '${{ toJSON(github.event.pull_request.body) }}' | jq -r .) | |
| PRIVACY=$(echo "$PR_BODY" | grep -oP '(?<=Visibility:\*\* ).*' | head -1 | xargs | tr '[:upper:]' '[:lower:]') | |
| if [[ "$PRIVACY" == "visible" ]]; then | |
| PRIVACY="closed" | |
| elif [[ "$PRIVACY" == "secret" ]]; then | |
| PRIVACY="secret" | |
| else | |
| echo "::error::Invalid visibility option: '$PRIVACY'" | |
| exit 1 | |
| fi | |
| DESCRIPTION=$(echo "$PR_BODY" | grep -oP '(?<=Purpose:\*\* ).*' | head -1 | xargs) | |
| MAINTAINERS=$(echo "$PR_BODY" | grep -oP '(?<=Maintainers:\*\* ).*' | head -1 | sed 's/none//' | xargs | sed 's/^,*//;s/,*$//') | |
| MEMBERS=$(echo "$PR_BODY" | grep -oP '(?<=Team Members:\*\* ).*' | head -1 | sed 's/none//' | xargs | sed 's/^,*//;s/,*$//') | |
| PARENT_TEAM=$(echo "$PR_BODY" | grep -oP '(?<=Parent Team:\*\* ).*' | head -1 | xargs) | |
| echo "TEAM_NAME=$TEAM_NAME" >> $GITHUB_ENV | |
| echo "PARENT_TEAM=${PARENT_TEAM:-none}" >> $GITHUB_ENV | |
| echo "PRIVACY=$PRIVACY" >> $GITHUB_ENV | |
| echo "DESCRIPTION=${DESCRIPTION:-Team created via automation}" >> $GITHUB_ENV | |
| echo "MAINTAINERS=${MAINTAINERS:-none}" >> $GITHUB_ENV | |
| echo "MEMBERS=${MEMBERS:-none}" >> $GITHUB_ENV | |
| - name: Create GitHub Team | |
| uses: actions/github-script@v6 | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_PAT }} | |
| with: | |
| github-token: ${{ secrets.GH_PAT }} | |
| script: | | |
| const teamSlug = process.env.TEAM_NAME.toLowerCase().replace(/[^a-z0-9-]/g, '-'); | |
| const org = context.repo.owner; | |
| const description = process.env.DESCRIPTION; | |
| const privacy = process.env.PRIVACY; | |
| const parentTeamName = process.env.PARENT_TEAM; | |
| const maintainers = process.env.MAINTAINERS; | |
| const members = process.env.MEMBERS; | |
| let parentTeamId; | |
| const commentLines = []; | |
| try { | |
| // Check if team exists | |
| let team; | |
| try { | |
| const { data } = await github.rest.teams.getByName({ org, team_slug: teamSlug }); | |
| team = data; | |
| console.log(`Team '${teamSlug}' already exists.`); | |
| } catch { | |
| // Get parent ID if provided | |
| if (parentTeamName && parentTeamName !== 'none') { | |
| try { | |
| const { data: parent } = await github.rest.teams.getByName({ | |
| org, | |
| team_slug: parentTeamName.toLowerCase().replace(/[^a-z0-9-]/g, '-') | |
| }); | |
| parentTeamId = parent.id; | |
| } catch (err) { | |
| console.warn(`Parent team '${parentTeamName}' not found.`); | |
| } | |
| } | |
| const { data } = await github.rest.teams.create({ | |
| org, | |
| name: process.env.TEAM_NAME, | |
| slug: teamSlug, | |
| description, | |
| privacy, | |
| ...(parentTeamId && { parent_team_id: parentTeamId }) | |
| }); | |
| team = data; | |
| console.log(`✅ Team '${team.name}' created.`); | |
| } | |
| // Add members | |
| const addMembers = async (userList, role) => { | |
| if (!userList || userList === 'none') return; | |
| const users = userList.split(',').map(u => u.trim()).filter(Boolean); | |
| for (const username of users) { | |
| try { | |
| await github.rest.teams.addOrUpdateMembershipForUserInOrg({ | |
| org, | |
| team_slug: team.slug, | |
| username, | |
| role | |
| }); | |
| console.log(`Added ${role}: ${username}`); | |
| } catch (error) { | |
| console.warn(`❌ Failed to add ${username} as ${role}: ${error.message}`); | |
| } | |
| } | |
| }; | |
| await addMembers(maintainers, 'maintainer'); | |
| await addMembers(members, 'member'); | |
| commentLines.push(`✅ Team **${team.name}** created or updated successfully`); | |
| commentLines.push(`• Visibility: ${privacy}`); | |
| commentLines.push(`• Description: ${description}`); | |
| if (parentTeamName !== 'none') commentLines.push(`• Parent Team: ${parentTeamName}`); | |
| if (maintainers !== 'none') commentLines.push(`• Maintainers: ${maintainers.replace(/,/g, ', ')}`); | |
| if (members !== 'none') commentLines.push(`• Members: ${members.replace(/,/g, ', ')}`); | |
| await github.rest.issues.createComment({ | |
| issue_number: context.payload.pull_request.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: commentLines.join('\n') | |
| }); | |
| } catch (error) { | |
| core.setFailed(`❌ Team creation failed: ${error.message}`); | |
| await github.rest.issues.createComment({ | |
| issue_number: context.payload.pull_request.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: `❌ Failed to create team: ${error.message}` | |
| }); | |
| } | |
| - name: Clean up team-name.txt | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_PAT }} | |
| run: | | |
| set -e | |
| git config --global user.name "github-actions" | |
| git config --global user.email "github-actions@github.com" | |
| if [ -f team-name.txt ]; then | |
| echo "Deleting team-name.txt..." | |
| git rm team-name.txt | |
| git commit -m "Cleanup: remove team-name.txt after team creation" | |
| git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }} | |
| git push origin HEAD | |
| echo "✅ team-name.txt deleted and changes pushed." | |
| else | |
| echo "::warning::team-name.txt not found to delete." | |
| fi | |