summaryrefslogtreecommitdiff
path: root/archived/projt-launcher/ci/github-script/get-teams.js
blob: c547d5ac62459e6615d307e9c5b579654aafc6fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
 * ProjT Launcher - Team Information Fetcher
 * Fetches team information from GitHub organization for CI purposes
 */

// Teams to exclude from processing (bots, voters, etc.)
const excludeTeams = [
  /^voters.*$/,
  /^bots?$/,
]

/**
 * Main function to fetch team information
 */
module.exports = async ({ github, context, core, outFile }) => {
  const withRateLimit = require('./withRateLimit.js')
  const { writeFileSync } = require('node:fs')

  const org = context.repo.owner
  const result = {}

  await withRateLimit({ github, core }, async () => {
    /**
     * Convert array of users to object mapping login -> id
     */
    function makeUserSet(users) {
      users.sort((a, b) => (a.login > b.login ? 1 : -1))
      return users.reduce((acc, user) => {
        acc[user.login] = user.id
        return acc
      }, {})
    }

    /**
     * Process teams recursively
     */
    async function processTeams(teams) {
      for (const team of teams) {
        // Skip excluded teams
        if (excludeTeams.some((regex) => team.slug.match(regex))) {
          core.info(`Skipping excluded team: ${team.slug}`)
          continue
        }

        core.notice(`Processing team ${team.slug}`)
        
        try {
          // Get team members
          const members = makeUserSet(
            await github.paginate(github.rest.teams.listMembersInOrg, {
              org,
              team_slug: team.slug,
              role: 'member',
            }),
          )
          
          // Get team maintainers
          const maintainers = makeUserSet(
            await github.paginate(github.rest.teams.listMembersInOrg, {
              org,
              team_slug: team.slug,
              role: 'maintainer',
            }),
          )
          
          result[team.slug] = {
            description: team.description,
            id: team.id,
            maintainers,
            members,
            name: team.name,
          }
        } catch (e) {
          core.warning(`Failed to fetch team ${team.slug}: ${e.message}`)
        }

        // Process child teams
        try {
          const childTeams = await github.paginate(
            github.rest.teams.listChildInOrg,
            {
              org,
              team_slug: team.slug,
            },
          )
          await processTeams(childTeams)
        } catch (e) {
          // Child teams might not exist or be accessible
          core.info(`No child teams for ${team.slug}`)
        }
      }
    }

    // Get all teams with access to the repository
    try {
      const teams = await github.paginate(github.rest.repos.listTeams, {
        ...context.repo,
      })
      
      core.info(`Found ${teams.length} teams with repository access`)
      await processTeams(teams)
    } catch (e) {
      core.warning(`Could not fetch repository teams: ${e.message}`)
      
      // Fallback: create minimal team structure
      result['projt-maintainers'] = {
        description: 'ProjT Launcher Maintainers',
        id: 0,
        maintainers: {},
        members: {},
        name: 'ProjT Maintainers',
      }
    }
  })

  // Sort teams alphabetically
  const sorted = Object.keys(result)
    .sort()
    .reduce((acc, key) => {
      acc[key] = result[key]
      return acc
    }, {})

  const json = `${JSON.stringify(sorted, null, 2)}\n`

  if (outFile) {
    writeFileSync(outFile, json)
    core.info(`Team information written to ${outFile}`)
  } else {
    console.log(json)
  }

  return sorted
}