Skip to content

Commit

Permalink
Restore organization membership automation (#229)
Browse files Browse the repository at this point in the history
* Restore organization membership automation

We have decided to resume using this tool to manage organization
membership. This change adds the organization config back along with a
new set of automation to manage it.

* Add CODEOWNERS file and update PR template
  • Loading branch information
accorvin authored Aug 26, 2024
1 parent 1821f5a commit d5c3466
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 71 deletions.
12 changes: 12 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Assigning ownership for specific files or directories
# Syntax: <file or directory path> <GitHub username or team>

# Assigning ownership for all files in a directory
# Syntax: <directory path>/* <GitHub username or team>

# Assigning ownership for all files in a repository
# Syntax: * <GitHub username or team>

* @opendatahub-io/Administrators

/config/organization_members.yaml @opendatahub-io/Administrators @opendatahub-io/org-membership-maintainers
59 changes: 0 additions & 59 deletions .github/ISSUE_TEMPLATE/membership_request.yaml

This file was deleted.

4 changes: 4 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!--- Provide a general summary of your changes in the Title above -->

## Description
<!--- Describe your changes in detail -->
65 changes: 65 additions & 0 deletions .github/workflows/apply-org-membership.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: Apply Organization Membership
on:
workflow_dispatch: {}
push:
branches:
- 'main'
paths:
- "config/organization_membership.yaml"
jobs:
merge_membership_config:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install python packages
run: pip install pyyaml
- name: Merge admins and members file
uses: jannekem/run-python-script-action@v1
with:
script: |
import yaml
with open('config/organization_admins.yaml') as f:
admins_data = yaml.safe_load(f)
with open('config/organization_members.yaml') as f:
members_data = yaml.safe_load(f)
merged_data = members_data.copy()
orgs = members_data['orgs'].keys()
for org in orgs:
org_admins = admins_data['orgs'].get(org, {}).get('admins', [])
merged_data['orgs'][org]['admins'] = org_admins
merged_data = admins_data | members_data
with open('config/organization_membership.yaml', 'w') as f:
yaml.dump(merged_data, f)
- name: Save the merged membership file
uses: actions/upload-artifact@master
with:
name: membership-config
path: config/
peribolos:
runs-on: ubuntu-latest
needs: merge_membership_config
container:
image: gcr.io/k8s-prow/peribolos
steps:
- name: Fetch the merged membership file
uses: actions/download-artifact@master
with:
name: membership-config
path: config/
- name: Apply organization membership
run: |
echo ${{ secrets.ORG_MANAGEMENT_TOKEN }} > /.github_token.txt
echo "Applying membership config:"
cat config/organization_membership.yaml
peribolos --github-token-path /.github_token.txt \
--config-path "config/organization_membership.yaml" \
--fix-org --fix-org-members --github-hourly-tokens="0" \
--min-admins=2 \
--confirm
109 changes: 109 additions & 0 deletions .github/workflows/verify-pull-requests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
name: Verify Pull Requests
on:
- pull_request
jobs:
yamllint:
name: Yamllint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Yamllint
uses: karancode/yamllint-github-action@master
with:
yamllint_comment: true
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
check-membership-config:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install python packages
run: pip install pyyaml
- name: Check user order
uses: jannekem/run-python-script-action@v1
with:
script: |
import yaml
def is_list_sorted(data):
return all(data[i].lower() <= data[i + 1].lower() \
for i in range(len(data) - 1))
with open('config/organization_members.yaml') as f:
data = yaml.safe_load(f)
orgs = data['orgs'].keys()
for org in orgs:
org_owners = data['orgs'][org].get('admins', [])
org_members = data['orgs'][org].get('members', [])
if not is_list_sorted(org_owners):
print((f'The list of owners for org {org} '
'is not in alphabetical order!'))
exit(1)
elif not is_list_sorted(org_members):
print((f'The list of members for org {org} '
'is not in alphabetical order!'))
exit(1)
- name: Check for individuals in both users and admins lists
uses: jannekem/run-python-script-action@v1
env:
ORG_OWNERS: ${{ secrets.ORG_OWNERS }}
with:
script: |
import os
import yaml
with open('config/organization_members.yaml') as f:
members_data = yaml.safe_load(f)
with open('config/organization_admins.yaml') as f:
owners_data = yaml.safe_load(f)
orgs = members_data['orgs'].keys()
for org in orgs:
org_owners = owners_data['orgs'][org].get('admins', [])
org_members = members_data['orgs'][org].get('members', [])
if len(set(org_owners).intersection(org_members)) > 0:
print(('There is a user listed in members that is '
f'also listed in owners for org {org}'))
exit(1)
- name: Check for duplicate individuals
uses: jannekem/run-python-script-action@v1
with:
script: |
import yaml
with open('config/organization_members.yaml') as f:
data = yaml.safe_load(f)
orgs = data['orgs'].keys()
for org in orgs:
org_owners = data['orgs'][org].get('admins', [])
org_members = data['orgs'][org].get('members', [])
if len(set(org_owners)) < len(org_owners):
print(('There is a duplicate user in the list of '
f'owners for org {org}'))
exit(1)
if len(set(org_members)) < len(org_members):
print(('There is a duplicate user in the list of '
f'members for org {org}'))
exit(1)
- name: Ensure that admins is not set
uses: jannekem/run-python-script-action@v1
with:
script: |
import yaml
with open('config/organization_members.yaml') as f:
data = yaml.safe_load(f)
orgs = data['orgs'].keys()
for org in orgs:
if 'admins' in data['orgs'][org].keys():
print(('Changes to the org membershp that change the list '
'of owners are not allowed.'))
exit(1)
56 changes: 44 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
# opendatahub-io GitHub organization
# org-management

This repository is no longer used to manage organization membership. Reach out to another
member of the OpenDataHub organization if you need to be added. If you do not know any
members of the OpenDataHub organization, membership in the opendatahub-io organization can be made by opening an [issue](https://github.com/opendatahub-io/org-management/issues/new/choose).
Configuration of organization membership and automation to apply this
membership via GitHub Actions automation.

Membership in the opendatahub-io project is governed by our
[community guidelines](https://github.com/opendatahub-io/opendatahub-community/blob/main/community-membership.md).
## Making Changes to Organization Membership

## Community, discussion, contribution, and support
Addition or removal of users to/from the organization should be made by editing
the [membership config][membership_config].

Learn how to engage with the opendatahub-io community on the
[community page](http://github.com/opendatahub-io/opendatahub-community/).
To add an individual to the organization, open a pull request adding the
individual's GitHub username to the membership config file. *Note* Please
add individuals in alphabetical order.

### Code of conduct
## Automation Setup

Participation in the Open Data Hub community is governed by the
[Open Data Hub Code of Conduct](https://github.com/opendatahub-io/opendatahub-community/blob/main/CODE_OF_CONDUCT.md).
We use [Peribolos](https://docs.prow.k8s.io/docs/components/cli-tools/peribolos/) to manage
organization membership. The membership is defined in [config/organization_members.yaml][membership_config].
We then use a GitHub action, defined in [.github/workflows/apply-org-membership.yaml](.github/workflows/apply-org-membership.yaml)
to automatically apply the membership after any change to the membership config.

This automation depends on a GitHub personal access token with read and write
permissions to organization members. The token value is saved in this repository as a
repository secret with name `ORG_MANAGEMENT_TOKEN`.

## CI/CD

We use GitHub actions to automate the functionality of this repository. To validate
new changes to this repository, we have a workflow called [Verify Pull Requests](.github/workflows/verify-pull-requests.yaml).
For every pull request to this repository, this will:

* Lint all YAML files
* Check that the list of organization users is alphabetical
* Ensure that there are no duplicate individuals
* Ensure that changes to organization owners are not being made

When changes to the membership config file are merged to main, an additional workflow
called [Apply Organization Membership](.github/workflows/apply-org-membership.yaml) is run. This
workflow runs the Peribolos tool and reconciles the state of the org membership to
the contencts of the config file.

## Managing Organization Owners

We want to prevent changes to the org management file that result in the state of organization owners
changing. The Peribolos tool currently requires that you specify owners when running it. To get around this
limitation we've split the organizational config into an [admin config](config/organization_admins.yaml) and
a [members config][membership_config]. These two configs are merged at apply time
and the merged config file is passed to Peribolos.

[membership_config]: config/organization_members.yaml
8 changes: 8 additions & 0 deletions config/organization_admins.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
orgs:
opendatahub-io:
admins:
- accorvin
- dchourasia
- jkoehler-redhat
- riprasad
Loading

0 comments on commit d5c3466

Please sign in to comment.