Skip to content

Commit

Permalink
Merge pull request #87 from multiformats/master-upgrade
Browse files Browse the repository at this point in the history
upgrade@7919415966
  • Loading branch information
galargh authored Feb 15, 2024
2 parents 0d23097 + 4afaf71 commit cda5afc
Show file tree
Hide file tree
Showing 17 changed files with 311 additions and 54 deletions.
8 changes: 7 additions & 1 deletion .github/actions/git-config-user/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ description: Configure git user
runs:
using: composite
steps:
- run: |
- if: github.event_name == 'workflow_dispatch'
run: |
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com>"
git config --global user.name "${GITHUB_ACTOR}"
shell: bash
- if: github.event_name != 'workflow_dispatch'
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
shell: bash
4 changes: 3 additions & 1 deletion .github/workflows/apply.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,6 @@ jobs:
SHA: ${{ needs.prepare.outputs.sha }}
run: gh run download -n "${TF_WORKSPACE}_${SHA}.tfplan" --repo "${GITHUB_REPOSITORY}"
- name: Terraform Apply
run: terraform apply -lock-timeout=0s -no-color "${TF_WORKSPACE}.tfplan"
run: |
terraform show -json > $TF_WORKSPACE.tfstate.json
terraform apply -lock-timeout=0s -no-color "${TF_WORKSPACE}.tfplan"
10 changes: 10 additions & 0 deletions .github/workflows/fix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ jobs:
run: npm ci && npm run build
working-directory: scripts
- name: Fix
id: fix
run: node lib/actions/fix-yaml-config.js
working-directory: scripts
- name: Upload YAML config
Expand All @@ -113,6 +114,15 @@ jobs:
path: github/${{ env.TF_WORKSPACE }}.yml
if-no-files-found: error
retention-days: 1
# NOTE(galargh, 2024-02-15): This will only work if GitHub as Code is used for a single organization
- name: Comment on pull request
if: github.event_name == 'pull_request_target' && steps.fix.outputs.comment
uses: marocchino/sticky-pull-request-comment@fcf6fe9e4a0409cd9316a5011435be0f3327f1e1 # v2.3.1
with:
header: fix
number: ${{ github.event.pull_request.number }}
message: ${{ steps.fix.outputs.comment }}

push:
needs: [prepare, fix]
permissions:
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/plan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ jobs:
run: terraform init
working-directory: terraform
- name: Plan terraform
run: terraform plan -refresh=false -lock=false -out="${TF_WORKSPACE}.tfplan" -no-color
run: |
terraform show -json > $TF_WORKSPACE.tfstate.json
terraform plan -refresh=false -lock=false -out="${TF_WORKSPACE}.tfplan" -no-color
working-directory: terraform
- name: Upload terraform plan
uses: actions/upload-artifact@v3
Expand Down Expand Up @@ -156,6 +158,7 @@ jobs:
- name: Comment on pull request
uses: marocchino/sticky-pull-request-comment@fcf6fe9e4a0409cd9316a5011435be0f3327f1e1 # v2.3.1
with:
header: plan
number: ${{ github.event.pull_request.number }}
message: |
Before merge, verify that all the following plans are correct. They will be applied as-is after the merge.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
upgrade:
uses: protocol/github-mgmt-template/.github/workflows/upgrade_reusable.yml@master
uses: pl-strflt/github-mgmt-template/.github/workflows/upgrade_reusable.yml@master
with:
ref: inputs.ref
secrets:
Expand Down
4 changes: 2 additions & 2 deletions docs/EXAMPLE.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ repositories: # This group defines repositories (https://registry.terraform.io/p
default_branch: master
delete_branch_on_merge: false
description: GitHub Management
homepage_url: https://github.com/protocol/github-mgmt-template
homepage_url: https://github.com/pl-strflt/github-mgmt-template
is_template: false
vulnerability_alerts: false
archive_on_destroy: true
Expand All @@ -87,7 +87,7 @@ repositories: # This group defines repositories (https://registry.terraform.io/p
branch: master
path: /docs
template:
owner: protocol
owner: pl-strflt
repository: github-mgmt-template
topics:
- github
8 changes: 4 additions & 4 deletions docs/HOWTOS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

*Example*

I want to invite `galargh` as an admin to `protocol` organization through GitHub Management.
I want to invite `galargh` as an admin to `pl-strflt` organization through GitHub Management.

I ensure the YAML configuration file has the following entry:
```yaml
Expand All @@ -29,7 +29,7 @@ I push my changes to a new branch and create a PR. An admin reviews the PR and m
*Example*
I want to demote `galargh` from being an `admin` of `protocol` organization to a regular `member` through GitHub Management.
I want to demote `galargh` from being an `admin` of `pl-strflt` organization to a regular `member` through GitHub Management.

I change the entry for `galargh` in the YAML configuration file from:
```yaml
Expand All @@ -54,7 +54,7 @@ I push my changes to a new branch and create a PR. An admin reviews the PR and m

*Example*

I want to be able to configure who the member of the `protocol` organization is through GitHub Management.
I want to be able to configure who the member of the `pl-strflt` organization is through GitHub Management.

I add `github_membership` to `resource_types` array in [terraform/locals_override.tf](../terraform/locals_override.tf). I push my changes to a new branch and create a PR. An admin reviews the PR and merges the PR if everything looks OK. Then, they synchronize GitHub Management with GitHub configuration.

Expand All @@ -67,7 +67,7 @@ I add `github_membership` to `resource_types` array in [terraform/locals_overrid

*Example*

I do not want to configure the roles of `protocol` organization members through GitHub Management anymore.
I do not want to configure the roles of `pl-strflt` organization members through GitHub Management anymore.

I ensure that `terraform/resources_override.tf` contains the following entry:
```tf
Expand Down
2 changes: 1 addition & 1 deletion scripts/__tests__/__resources__/files/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# GitHub Management via Terraform: pl-strflt

This repository is responsible for managing GitHub configuration of `pl-strflt` organisation as code with Terraform. It was created from [github-mgmt-template](https://github.com/protocol/github-mgmt-template) and it will receive updates from that repository.
This repository is responsible for managing GitHub configuration of `pl-strflt` organisation as code with Terraform. It was created from [github-mgmt-template](https://github.com/pl-strflt/github-mgmt-template) and it will receive updates from that repository.

**IMPORTANT**: Having write access to GitHub Management repository can be as powerful as having admin access to the organizations managed by that repository.

Expand Down
2 changes: 1 addition & 1 deletion scripts/__tests__/__resources__/github/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ repositories:
triage:
- ipdx
template:
owner: protocol
owner: pl-strflt
repository: github-mgmt-template
visibility: public
vulnerability_alerts: false
Expand Down
4 changes: 2 additions & 2 deletions scripts/__tests__/__resources__/terraform/terraform.tfstate
Original file line number Diff line number Diff line change
Expand Up @@ -1409,7 +1409,7 @@
"svn_url": "https://github.com/pl-strflt/github-mgmt",
"template": [
{
"owner": "protocol",
"owner": "pl-strflt",
"repository": "github-mgmt-template"
}
],
Expand Down Expand Up @@ -1794,7 +1794,7 @@
"commit_email": "[email protected]",
"commit_message": "Update README",
"commit_sha": "ff32de62d3dd9bc01a2dabd8439d413e8a250dfe",
"content": "# GitHub Management via Terraform: pl-strflt\n\nThis repository is responsible for managing GitHub configuration of `pl-strflt` organisation as code with Terraform. It was created from [github-mgmt-template](https://github.com/protocol/github-mgmt-template) and it will receive updates from that repository.\n\n**IMPORTANT**: Having write access to GitHub Management repository can be as powerful as having admin access to the organizations managed by that repository.\n\n*NOTE*: Because we don't have merge queue functionality enabled for the repository yet, after a merge, wait for the `Apply` and `Update` workflows to complete before merging any other PRs.\n\nTo learn more, check out:\n- [What is GitHub Management and how does it work?](docs/ABOUT.md)\n- [How to set up GitHub Management?](docs/SETUP.md)\n- [How to work with GitHub Management?](docs/HOWTOS.md)\n",
"content": "# GitHub Management via Terraform: pl-strflt\n\nThis repository is responsible for managing GitHub configuration of `pl-strflt` organisation as code with Terraform. It was created from [github-mgmt-template](https://github.com/pl-strflt/github-mgmt-template) and it will receive updates from that repository.\n\n**IMPORTANT**: Having write access to GitHub Management repository can be as powerful as having admin access to the organizations managed by that repository.\n\n*NOTE*: Because we don't have merge queue functionality enabled for the repository yet, after a merge, wait for the `Apply` and `Update` workflows to complete before merging any other PRs.\n\nTo learn more, check out:\n- [What is GitHub Management and how does it work?](docs/ABOUT.md)\n- [How to set up GitHub Management?](docs/SETUP.md)\n- [How to work with GitHub Management?](docs/HOWTOS.md)\n",
"file": "README.md",
"id": "github-mgmt/README.md",
"overwrite_on_create": false,
Expand Down
100 changes: 100 additions & 0 deletions scripts/src/actions/shared/get-access-summary-description.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {Config} from '../../yaml/config'
import { State } from '../../terraform/state'
import { RepositoryCollaborator } from '../../resources/repository-collaborator'
import { Member } from '../../resources/member'
import { TeamMember } from '../../resources/team-member'
import { RepositoryTeam } from '../../resources/repository-team'

function getAccessSummaryFrom(source: State | Config): Record<string, any> {
const members = source.getResources(Member)
const teamMembers = source.getResources(TeamMember)
const teamRepositories = source.getResources(RepositoryTeam)
const repositoryCollaborators = source.getResources(RepositoryCollaborator)

const usernames = new Set<string>([
...members.map(member => member.username),
...repositoryCollaborators.map(collaborator => collaborator.username),
])

const accessSummary: Record<string, any> = {}

for (const username of usernames) {
const role = members.find(member => member.username === username)?.role
const teams = teamMembers.filter(teamMember => teamMember.username === username).map(teamMember => teamMember.team)
const repositoryCollaborator = repositoryCollaborators.filter(repositoryCollaborator => repositoryCollaborator.username === username)
const teamRepository = teamRepositories.filter(teamRepository => teams.includes(teamRepository.team))

const repositories: Record<string, any> = {}

for (const rc of repositoryCollaborator) {
repositories[rc.repository] = repositories[rc.repository] ?? []
repositories[rc.repository].push({permission: rc.permission, type: 'collaborator'})
}

for (const tr of teamRepository) {
repositories[tr.repository] = repositories[tr.repository] ?? []
repositories[tr.repository].push({permission: tr.permission, type: 'team', team: tr.team})
}

accessSummary[username] = {
role,
teams,
repositories
}
}

return accessSummary
}

function describeAccessSummary(accessSummary: Record<string, any>): string {
const lines: string[] = []
const permissions = ['admin', 'maintain', 'push', 'triage', 'pull']

for (const [username, summary] of Object.entries(accessSummary)) {
lines.push(`User @${username}:`)
if (summary.role !== undefined) {
lines.push(` - is a ${summary.role} of the organization`)
} else {
lines.push(` - is not a member of the organization`)
}
if (Object.keys(summary.repositories).length > 0) {
for (const permission of permissions) {
const buffer = []
const index = permission.indexOf(permission)
for (const [repository, accessList] of Object.entries(summary.repositories) as [string, any][]) {
const access = accessList.find((a: any) => a.permission === permission)
if (access !== undefined) {
const higher = accessList.filter((a: any) => permissions.indexOf(a.permission) < index)
if (higher.length === 0) {
if (access.type === 'collaborator') {
buffer.push(` - ${repository} as a direct collaborator`)
} else {
buffer.push(` - ${repository} through team @${access.team}`)
}
}
}
}
if (buffer.length > 0) {
lines.push(` - has ${permission} access to:`)
lines.push(...buffer)
} else {
lines.push(` - has no ${permission} access to any repository`)
}
}
} else {
lines.push(` - has no access to any repository`)
}
}

return lines.join('\n')
}

export async function getAccessSummaryDescription(): Promise<string> {
const config = Config.FromPath()

const accessSummary = getAccessSummaryFrom(config)

const description = describeAccessSummary(accessSummary)

return description
}
33 changes: 33 additions & 0 deletions scripts/src/actions/shared/toggle-archived-repos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {Config} from '../../yaml/config'
import {Repository} from '../../resources/repository'
import { State } from '../../terraform/state'

export async function toggleArchivedRepos(): Promise<void> {
const state = await State.New()
const config = Config.FromPath()

const resources = state.getAllResources()
const stateRepositories = state.getResources(Repository)
const configRepositories = config.getResources(Repository)

for (const configRepository of configRepositories) {
if (configRepository.archived) {
config.removeResource(configRepository)
const repository = new Repository(configRepository.name)
repository.archived = true
config.addResource(repository)
} else {
const stateRepository = stateRepositories.find(r => r.name === configRepository.name)
if (stateRepository !== undefined && stateRepository.archived) {
config.addResource(stateRepository)
for (const resource of resources) {
if ('repository' in resource && resource.repository === stateRepository.name) {
config.addResource(resource)
}
}
}
}
}

config.save()
}
12 changes: 11 additions & 1 deletion scripts/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import 'reflect-metadata'
import {sync} from './sync'
import {State} from './terraform/state'
import {Config} from './yaml/config'
import { toggleArchivedRepos } from './actions/shared/toggle-archived-repos'

async function run(): Promise<void> {
async function runSync(): Promise<void> {
const state = await State.New()
const config = Config.FromPath()

Expand All @@ -12,4 +13,13 @@ async function run(): Promise<void> {
config.save()
}

async function runToggleArchivedRepos(): Promise<void> {
await toggleArchivedRepos()
}

async function run(): Promise<void> {
await runSync()
await runToggleArchivedRepos()
}

run()
23 changes: 23 additions & 0 deletions scripts/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,26 @@ export function yamlify(value: any): YAML.ParsedNode {
}
return node
}

export function globToRegex(globPattern: string): RegExp {
const regexPattern = globPattern
.split('')
.map(char => {
if (char === '*') {
return '.*'
} else if (char === '?') {
return '.'
} else if (
['.', '\\', '+', '(', ')', '[', ']', '{', '}', '|', '^', '$'].includes(
char
)
) {
return `\\${char}`
} else {
return char
}
})
.join('')

return new RegExp(`^${regexPattern}$`)
}
Loading

0 comments on commit cda5afc

Please sign in to comment.