gomgr

command module
v0.1.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 20, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

github-org-manager-go (gomgr)

Build Go Reference Go Report Card License GitHub release GitHub issues

A fast, idempotent GitHub Organization Manager written in Go. Define your org as YAML and apply it with a single command. Ships with a release workflow and a CI workflow to run sync against one or many org-config folders.

Highlights

  • ✅ YAML-driven org config (app.yaml, org.yaml, teams/*.yaml)
  • ✅ Teams, maintainers, members (idempotent add/update)
  • ✅ Repo permission grants (pull/triage/push/maintain/admin)
  • Repository topics: add topics/labels to repositories for organization
  • Repository pinning: pin important repositories to organization profile
  • Optional: create repos that don’t exist (create_repo: true)
  • Optional: inject .github/renovate.json into repos
  • ✅ Warnings & cleanups: unmanaged teams, members without team, unmanaged repos
  • Optional hard cleanups: delete unmanaged teams, remove members without team, delete unmanaged repos
  • ✅ Auth: GitHub App (recommended) or PAT
  • --dry plan with stable output; safe apply
  • ✅ Cross‑platform binaries via GitHub Releases; gomgr version stamped at build

Install

Option 1 — Download a release

Grab a binary from Releases and put it on your $PATH.

gomgr version
Option 2 — Build from source
go build -trimpath -buildvcs=true -ldflags "-s -w -X github.com/DragonSecurity/github-org-manager-go/internal/version.Version=$(git describe --tags --always --dirty)" -o gomgr .

Quickstart

  1. Prepare config directory (example shown below):
<config>/
├─ app.yaml
├─ org.yaml
└─ teams/
   └─ platform-team.yaml
  1. Auth (choose one):
  • GitHub App (recommended)

    export GITHUB_APP_ID=1719369
    export GITHUB_APP_PRIVATE_KEY="$(cat /path/to/private-key.pem)"   # or set app.yaml: private_key: <path or PEM>
    

    Installation: install the app on your target org and grant the permissions listed below.

  • PAT

    export GITHUB_TOKEN=<personal-access-token>
    
  1. Run a dry run, then apply
gomgr sync -c <config> --dry
gomgr sync -c <config>

Configuration

app.yaml
org: KaMuses
# GitHub App auth (preferred):
app_id: 1719369                 # or set via env GITHUB_APP_ID
private_key: ./app-private.pem  # file path or raw PEM; env GITHUB_APP_PRIVATE_KEY also works

dry_warnings:
  warn_unmanaged_teams: true
  warn_members_without_any_team: true
  warn_unmanaged_repos: true         # warn about repos not defined in any team

# Optional enforcement / extras:
remove_members_without_team: true   # remove org members not in any team
delete_unconfigured_teams: true     # delete teams not defined in YAML
delete_unmanaged_repos: false       # delete repos not defined in any team (DESTRUCTIVE!)
create_repo: true                   # create repos if missing when referenced by teams
add_renovate_config: true           # create .github/renovate.json in repos
renovate_config: |
  {
    "$schema": "https://docs.renovatebot.com/renovate-schema.json",
    "extends": ["github>DragonSecurity/renovate-presets"]
  }
org.yaml

Currently used for owners (extension point):

owners:
  - alice
  - bob
teams/*.yaml
name: Platform Team
slug: platform-team            # optional; default = kebab(name)
description: Core platform engineers
privacy: closed                # closed | secret
parents: []                    # (future enhancement)
maintainers:
  - alice
members:
  - bob
repositories:
  # Simple permission string (backward compatible)
  infra: maintain              # pull|triage|push|maintain|admin
  
  # Advanced config with topics and pinning
  api:
    permission: push
    topics:
      - backend
      - api
      - project-platform
  
  # Repository with pinning (appears on org profile)
  platform-index:
    permission: admin
    topics:
      - project-platform
      - documentation
    pinned: true

Loader ignores non‑YAML files in teams/ and skips empty/invalid entries.


Project Organization Pattern

gomgr supports organizing repositories by project with topics, pinning, and naming conventions:

Example: Multi-repo project setup

  1. Define a project name (slug), e.g., platform
  2. Prefix all project repositories: platform-api, platform-web, platform-infra
  3. Tag all repos with topic: project-platform
  4. Create an index repository: platform-index with README linking to all project repos
  5. Pin the index repo to make it prominent on the org profile

Example configuration:

name: Platform Team
repositories:
  platform-index:
    permission: admin
    topics:
      - project-platform
      - documentation
    pinned: true
  
  platform-api:
    permission: push
    topics:
      - project-platform
      - backend
  
  platform-web:
    permission: push
    topics:
      - project-platform
      - frontend
  
  platform-infra:
    permission: maintain
    topics:
      - project-platform
      - infrastructure

This pattern makes it easy to:

  • Discover all repositories belonging to a project using GitHub's topic search
  • Provide project documentation via the pinned index repository
  • Maintain consistent naming and organization across projects

Auth & Permissions

Set GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY (or app_id/private_key in app.yaml). The app must be installed on the org.

Typical minimum permissions (tighten to least privilege for your use-case):

  • Organization: Members (Read/Write), Teams (Read/Write)
  • Repository: Administration (Read/Write) to grant team access & create repos; Contents (Read/Write) to create files like Renovate config; Metadata (Read)

Exact permissions depend on which features you enable (e.g., if you don’t create repos or write files, you can drop those).

Personal Access Token (PAT)

Use a classic PAT with scopes:

  • admin:org (manage teams/members)
  • repo (set team repo access and create repos)
  • read:org (read org metadata)

CLI

  • gomgr sync -c <config> [--dry] [--debug]
    Plans and applies org state.

  • gomgr setup-team -n "Team Name" -c <config> [-f out/path.yaml]
    Bootstraps a team YAML.

  • gomgr version
    Prints version (stamped at build). If built with VCS info, also prints revision/dirty/commit time.

Order of operations (apply):
create teams → set memberships → ensure repos → grant permissions → write renovate (optional) → set topics & pins → cleanups (optional)


CI: Releases

This repo includes .github/workflows/release.yml:

  • Trigger on tag push (v*.*.*) or manual.
  • Builds for linux/darwin/windows × amd64/arm64.
  • Stamps gomgr version via -ldflags.
  • Uploads packaged artifacts and checksums.txt.

Tag to release:

git tag v0.1.0
git push origin v0.1.0

CI: Org sync workflow (for your org-config repo)

Example (.github/workflows/org-sync.yml):

name: Synchronise organization users and teams (gomgr)

on:
  push:
    branches: [ "main" ]
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
      matrix:
        config:
          - { folder: "dragonsecurity/dragonsecurity", gom_version: "v0.12.2" }
          - { folder: "dragonsecurity/dragondevcc",   gom_version: "v0.10.2" }
          - { folder: "dragonsecurity/kamuses",       gom_version: "v0.10.2" }
    continue-on-error: true  # allow other matrix jobs to finish if one fails

    steps:
      - uses: actions/checkout@v4
      - name: Install gh
        uses: cli/gh-action@v2
      - name: Download gomgr
        env: { GH_TOKEN: ${{ github.token }} }
        run: |
          VERSION="${{ matrix.config.gom_version }}"
          OS=linux ARCH=amd64
          ASSET="gomgr_${VERSION}_${OS}_${ARCH}.tar.gz"
          mkdir -p .gomgr
          gh release download "$VERSION" --repo DragonSecurity/github-org-manager-go --pattern "$ASSET" --dir .gomgr
          tar -xzf ".gomgr/$ASSET" -C .gomgr
          sudo mv $(find .gomgr -type f -name gomgr) /usr/local/bin/gomgr
          sudo chmod +x /usr/local/bin/gomgr
      - run: gomgr version
      - name: Synchronise settings
        run: gomgr sync -c ${{ matrix.config.folder }}
        env:
          GITHUB_APP_PRIVATE_KEY: ${{ secrets.DSEC_USER_MANAGEMENT_APP_PRIVATE_KEY }}
          GITHUB_APP_ID: "1719369"

Development

Testing

The project includes a comprehensive test suite and Makefile for development:

# Run all tests
make test

# Run tests with coverage report
make test-coverage

# Run verbose tests
make test-verbose

# Check code formatting
make fmt-check

# Format code
make fmt

# Run go vet
make vet
Code Quality Tools

Install development tools (golangci-lint, gosec):

make install-tools

Run code quality checks:

# Run linter
make lint

# Run security scanner
make security

# Run all basic checks (format, vet, test)
make check

# Run all checks including lint and security
make check-all
Building
# Build binary
make build

# Clean build artifacts
make clean

# Run full CI pipeline
make ci
CI/CD

The repository includes GitHub Actions workflows:

  • .github/workflows/ci.yaml: Runs tests, linting, and security checks on every push/PR
  • .github/workflows/release.yaml: Builds and releases binaries on version tags

Troubleshooting

  • 404 on /teams//members: empty/invalid team YAML or calling membership on a team that doesn’t exist yet. Loader ignores non‑YAML files and planner guards empty slugs; team creation happens before membership.
  • gomgr version shows dev: build without -ldflags -X or not from a tag. Use the release workflow or pass a version when building.
  • Renovate config not created: ensure add_renovate_config: true and renovate_config is non‑empty; repo must exist or create_repo: true.

Roadmap / TODO

  • Compare & update team fields (description/privacy/parents)
  • Optionally remove extra team members / revoke extra repo perms
  • Optionally remove extra topics from repos (current behavior: union of all topics)
  • Custom default branch for file writes
  • Parallel apply with rate‑limit aware workers
  • More comprehensive plan diff output

Contributing

PRs welcome! Please:

  • open an issue first for larger changes,
  • keep commits small & focused,
  • add tests where practical,
  • run make check before submitting (or make check-all for full checks including linting),
  • ensure make build succeeds.

See the Development section above for available commands and tooling.


Security

This tool modifies org membership and repository access. Use dry‑run in CI and restrict credentials using least privilege. Prefer GitHub Apps over PATs.


License

See LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
gh

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL