Pular para o conteúdo principal

Grupos/Organizações

ELT85B-N21-2026-2 Teams​

for letter in A B C D E F G H I J K L M P; do
gh api --method POST --silent orgs/ELT85B-N21-2026-2/teams \
-f name="Grupo-$letter" \
-f privacy="closed"
done
Organization: ELT85B-N21-2026-2
│
├── Teams
│ ├── Grupo-A
│ ├── Grupo-B
│ ├── Grupo-C
│ └── ...
│
└── Repositories
├── lab00-template
├── lab00-grupo-a
├── lab00-grupo-b
├── ...
├── lab10-template
├── lab10-grupo-a
├── lab10-grupo-b
├── ...
├── projeto-template
├── projeto-grupo-a
├── projeto-grupo-b
└── ...

List your teams and their slugs:

gh api orgs/ELT85B-N21-2026-2/teams --jq '.[] | "\(.name) → \(.slug)"'

List members

gh api orgs/ELT85B-N21-2026-2/teams/grupo-a/members --jq '.[].login'

List repos for a team

gh api orgs/ELT85B-N21-2026-2/teams/grupo-a/repos --jq '.[].full_name'

Here’s a script that creates the lab templates (lab00-template, lab01-template, …):

#!/bin/bash

ORG="ELT85B-N21-2026-2"
NLABS=10 # Creates lab00-template → lab10-template

echo "Creating lab templates in organization: $ORG"
echo ""

for lab in $(seq -w 0 $NLABS); do
REPO="lab${lab}-template"

echo "Creating $REPO..."

# Create the repository
gh repo create "$ORG/$REPO" \
--private \
--description "Template for LAB$lab" \
--add-readme \
--silent

# Mark it as a template repository
gh api --method PATCH --silent \
"repos/$ORG/$REPO" \
-f is_template=true

echo " ✓ $REPO created and marked as template"
done

echo ""
echo "All lab templates created successfully!"
echo ""
echo "You can now use them like this:"
echo " TEMPLATE=\"$ORG/lab05-template\""
./scripts/create-labs-template.sh

Create only one specific template

ORG="ELT85B-N21-2026-2"
NLAB=0
LAB=$(printf "%02d" $NLAB)
REPO="lab${LAB}-template"

gh repo create "$ORG/$REPO" \
--private \
--description "Template for LAB$LAB" \
--add-readme

gh api --method PATCH \
"repos/$ORG/$REPO" \
-f is_template=true
./scripts/create-lab-template.sh
#!/bin/bash
set -e

ORG="ELT85B-N21-2026-2"
GROUP_LIST="A B C D E F G H I J K L M P" # ← not GROUPS
NLAB=0
LAB=$(printf "lab%02d" "$NLAB")
TEMPLATE="$ORG/${LAB}-template"

echo "GROUP_LIST=[$GROUP_LIST]"
echo "Creating ${LAB}-grupo-* from $TEMPLATE"
echo ""

for letter in $GROUP_LIST; do
GROUP_LOWER=$(echo "$letter" | tr '[:upper:]' '[:lower:]')
TEAM_SLUG="grupo-${GROUP_LOWER}"
REPO="${LAB}-grupo-${GROUP_LOWER}"

echo "→ $REPO (team: $TEAM_SLUG)"

if gh repo view "$ORG/$REPO" &>/dev/null; then
echo " ⚠ already exists, skipping create"
else
gh repo create "$ORG/$REPO" \
--private \
--template "$TEMPLATE" \
--description "LAB$(printf '%02d' "$NLAB") - Grupo $letter"
fi

if gh api --method PUT --silent \
"orgs/$ORG/teams/$TEAM_SLUG/repos/$ORG/$REPO" \
-f permission=push; then
echo " ✓ https://github.com/$ORG/$REPO"
else
echo " ✗ Failed to add team $TEAM_SLUG"
fi
done

echo ""
echo "Done."
./scripts/create-lab-from-template.sh

Cheatsheet for your org​

ORG="ELT85B-N21-2026-2"

# List teams
gh api "orgs/$ORG/teams" --jq '.[] | "\(.name) → \(.slug)"'

# Create all groups
for L in A B C D E F G H I J K L M X; do
gh api --method POST "orgs/$ORG/teams" \
-f name="Grupo-$L" -f privacy="closed" --silent
done

# Give team write on a lab repo
gh api --method PUT \
"orgs/$ORG/teams/grupo-a/repos/$ORG/lab00-grupo-a" \
-f permission="push"

# Add a student to a team
gh api --method PUT \
"orgs/$ORG/teams/grupo-a/memberships/student-username" \
-f role="member"

ELT85B-N21-2026-2 Teams (TODO)​

for letter in A B C D E F G H I J X; do
gh api --method POST orgs/ELT85B-N21-2026-2/teams \
-f name="Grupo-$letter" \
-f privacy="closed"
done
for letter in A B C D E F G H I J K L M X; do
gh api --method POST orgs/ELT85B-N21-2026-2/teams \
-f name="Grupo-$letter" \
-f privacy="closed"
done
for letter in A B C D E F G H I J K L M X; do
gh api --method POST --silent orgs/ELT85B-N21-2026-2/teams \
-f name="Grupo-$letter" \
-f privacy="closed"
done
Organization: ELT85B-N21-2026-2
│
├── Teams
│ ├── Grupo-A
│ ├── Grupo-B
│ ├── Grupo-C
│ └── ...
│
└── Repositories
├── grupo-a-lab00
├── grupo-a-lab01
├── ...
├── grupo-a-lab10
├── grupo-b-lab00
├── grupo-b-lab01
└── ...

Bulk Creation Script (Git Bash)​

Here’s a ready-to-use script that creates LAB00 to LAB10 for every group:

ORG="ELT85B-N21-2026-2"
GROUPS="A B C D E F G H I J K L M X"

for letter in $GROUPS; do
TEAM="Grupo-$letter"

for lab in $(seq -w 0 10); do # 00, 01, 02 ... 10
REPO="grupo-${letter,,}-lab$lab" # grupo-a-lab00, grupo-b-lab01...

echo "Creating $REPO for $TEAM..."

gh repo create "$ORG/$REPO" \
--private \
--team "$TEAM" \
--description "LAB$lab - Grupo $letter" \
--add-readme \
--silent

# Give the team write access (instead of just read)
gh api --method PUT --silent \
"orgs/$ORG/teams/$TEAM/repos/$ORG/$REPO" \
-f permission=push
done
done

Projeto​

ORG="ELT85B-N21-2026-2"
GROUPS="A B C D E F G H I J K L M X"

for letter in $GROUPS; do
TEAM="Grupo-$letter"
REPO="grupo-${letter,,}-projeto" # grupo-a-projeto, grupo-b-projeto...

echo "Creating $REPO for $TEAM..."

gh repo create "$ORG/$REPO" \
--private \
--team "$TEAM" \
--description "Projeto Final - Grupo $letter" \
--add-readme \
--silent

# Give the team write access
gh api --method PUT --silent \
"orgs/$ORG/teams/$TEAM/repos/$ORG/$REPO" \
-f permission=push
done

Here’s the merged complete script with a NLABS variable:​

#!/bin/bash

ORG="ELT85B-N21-2026-2"
GROUPS="A B C D E F G H I J K L M P"
NLABS=10 # Creates LAB00 to LAB10

for letter in $GROUPS; do
TEAM="Grupo-$letter"
GROUP_LOWER="${letter,,}" # a, b, c...

echo "=== Processing Grupo-$letter ==="

# ---------- Create LAB repositories ----------
for lab in $(seq -w 0 $NLABS); do
REPO="grupo-${GROUP_LOWER}-lab$lab"

echo " Creating $REPO..."

gh repo create "$ORG/$REPO" \
--private \
--team "$TEAM" \
--description "LAB$lab - Grupo $letter" \
--add-readme \
--silent

# Give write access to the team
gh api --method PUT --silent \
"orgs/$ORG/teams/$TEAM/repos/$ORG/$REPO" \
-f permission=push
done

# ---------- Create Projeto repository ----------
REPO="grupo-${GROUP_LOWER}-projeto"

echo " Creating $REPO..."

gh repo create "$ORG/$REPO" \
--private \
--team "$TEAM" \
--description "Projeto Final - Grupo $letter" \
--add-readme \
--silent

gh api --method PUT --silent \
"orgs/$ORG/teams/$TEAM/repos/$ORG/$REPO" \
-f permission=push

echo ""
done

echo "All repositories created successfully!"
bash create-repos.sh

What it creates (example for Grupo-A)​

grupo-a-lab00
grupo-a-lab01
grupo-a-lab02
...
grupo-a-lab10
grupo-a-projeto

Here’s a focused script that creates repositories for one specific lab using a template:​

#!/bin/bash

ORG="ELT85B-N21-2026-2"
TEMPLATE="ELT85B-N21-2026-2/lab-template" # ← change to your template repo
GROUPS="A B C D E F G H I J K L M X"
NLAB=5 # ← creates lab05

LAB=$(printf "%02d" $NLAB) # turns 5 into "05"

echo "Creating repositories for LAB$LAB using template: $TEMPLATE"
echo ""

for letter in $GROUPS; do
TEAM="Grupo-$letter"
GROUP_LOWER="${letter,,}"
REPO="grupo-${GROUP_LOWER}-lab$LAB"

echo "Creating $REPO for $TEAM..."

gh repo create "$ORG/$REPO" \
--template "$TEMPLATE" \
--private \
--team "$TEAM" \
--description "LAB$LAB - Grupo $letter" \
--silent

# Give the team write access
gh api --method PUT --silent \
"orgs/$ORG/teams/$TEAM/repos/$ORG/$REPO" \
-f permission=push

echo " ✓ $REPO created"
done

echo ""
echo "All LAB$LAB repositories created successfully!"

Here’s a script that creates the lab templates (lab00-template, lab01-template, …):​

#!/bin/bash

ORG="ELT85B-N21-2026-2"
NLABS=10 # Creates lab00-template → lab10-template

echo "Creating lab templates in organization: $ORG"
echo ""

for lab in $(seq -w 0 $NLABS); do
REPO="lab${lab}-template"

echo "Creating $REPO..."

# Create the repository
gh repo create "$ORG/$REPO" \
--private \
--description "Template for LAB$lab" \
--add-readme \
--silent

# Mark it as a template repository
gh api --method PATCH --silent \
"repos/$ORG/$REPO" \
-f is_template=true

echo " ✓ $REPO created and marked as template"
done

echo ""
echo "All lab templates created successfully!"
echo ""
echo "You can now use them like this:"
echo " TEMPLATE=\"$ORG/lab05-template\""

Optional: Create only one specific template

ORG="ELT85B-N21-2026-2"
NLAB=5
LAB=$(printf "%02d" $NLAB)
REPO="lab${LAB}-template"

gh repo create "$ORG/$REPO" \
--private \
--description "Template for LAB$LAB" \
--add-readme

gh api --method PATCH \
"repos/$ORG/$REPO" \
-f is_template=true

GitHub CLI team management​

GitHub CLI team management

The official gh CLI does not have a dedicated gh team command. Team operations are done with gh api (REST API) or with community extensions.


1. Prerequisites​

# Auth with org permissions
gh auth login
gh auth refresh -h github.com -s admin:org,read:org,repo
ScopePurpose
read:orgList teams / members
admin:orgCreate / update / delete teams
repoGrant teams access to repos

Git Bash tip: omit the leading / in API paths (orgs/... not /orgs/...).

Bash tip: do not name a variable GROUPS — it is a special Bash array (that caused your 197121 issue).


2. Core concepts​

ConceptMeaningExample
NameDisplay nameGrupo-A
SlugURL/API id (lowercase)grupo-a
Privacyclosed or secretclosed
Permission on repopull, push, maintain, adminpush = write

Always use the slug in API paths.

gh api orgs/ELT73A-S22-2026-2/teams --jq '.[] | "\(.name) → \(.slug)"'

3. Common operations with gh api​

List teams​

gh api orgs/ELT73A-S22-2026-2/teams --jq '.[] | {name, slug, privacy}'

Get one team​

gh api orgs/ELT73A-S22-2026-2/teams/grupo-a

Create a team​

gh api --method POST orgs/ELT73A-S22-2026-2/teams \
-f name="Grupo-A" \
-f description="Students group A" \
-f privacy="closed"

Update a team​

gh api --method PATCH orgs/ELT73A-S22-2026-2/teams/grupo-a \
-f description="Updated description" \
-f privacy="closed"

Delete a team​

gh api --method DELETE orgs/ELT73A-S22-2026-2/teams/grupo-a

Nested (parent) team​

PARENT_ID=$(gh api orgs/ELT73A-S22-2026-2/teams/grupo-a --jq '.id')

gh api --method POST orgs/ELT73A-S22-2026-2/teams \
-f name="Grupo-A-Frontend" \
-f privacy="closed" \
-F parent_team_id="$PARENT_ID"

4. Members​

List members​

gh api orgs/ELT73A-S22-2026-2/teams/grupo-a/members --jq '.[].login'

Add member​

# role: member | maintainer
gh api --method PUT \
orgs/ELT73A-S22-2026-2/teams/grupo-a/memberships/USERNAME \
-f role="member"

Remove member​

gh api --method DELETE \
orgs/ELT73A-S22-2026-2/teams/grupo-a/memberships/USERNAME

Bulk add members​

for user in alice bob carol; do
gh api --method PUT --silent \
orgs/ELT73A-S22-2026-2/teams/grupo-a/memberships/$user \
-f role="member"
echo "Added $user"
done

5. Team ↔ repository access​

Grant access​

gh api --method PUT \
orgs/ELT73A-S22-2026-2/teams/grupo-a/repos/ELT73A-S22-2026-2/lab00-grupo-a \
-f permission="push"
permissionMeaning
pullRead
triageTriage
pushWrite
maintainMaintain
adminAdmin

List repos for a team​

gh api orgs/ELT73A-S22-2026-2/teams/grupo-a/repos --jq '.[].full_name'

Remove team from a repo​

gh api --method DELETE \
orgs/ELT73A-S22-2026-2/teams/grupo-a/repos/ELT73A-S22-2026-2/lab00-grupo-a

Note on gh repo create​

  • --team grants access at create time, but only pull (read) and cannot be combined with --template.
  • Pattern you already use: create from template → then PUT team with push.

6. Where teams appear in native gh​

CommandTeam-related behavior
gh repo create --team NAMEAdd team with read (no --template)
gh pr create --reviewer org/team-slugRequest team review
gh project link --team ...Link project to a team
gh org listList orgs only (not teams)

Everything else → gh api.


7. Optional extensions​

Higher-level team commands:

# Team CRUD, members, repos
gh extension install srz-zumix/gh-team-kit

# Examples
gh team-kit list
gh team-kit create "Grupo-A" --description "..."
gh team-kit tree
# Repo collaborators + teams
gh extension install mislav/gh-repo-collab
gh repo-collab add ORG/REPO org/team-slug --permission push
# Org extras (members/teams)
gh extension install Kyuubang/gh-org-extras

Core gh api is enough for your lab setup and avoids extra dependencies.


8. Cheatsheet for your org​

ORG="ELT73A-S22-2026-2"

# List teams
gh api "orgs/$ORG/teams" --jq '.[] | "\(.name) → \(.slug)"'

# Create all groups
for L in A B C D E F G H I J K L M X; do
gh api --method POST "orgs/$ORG/teams" \
-f name="Grupo-$L" -f privacy="closed" --silent
done

# Give team write on a lab repo
gh api --method PUT \
"orgs/$ORG/teams/grupo-a/repos/$ORG/lab00-grupo-a" \
-f permission="push"

# Add a student to a team
gh api --method PUT \
"orgs/$ORG/teams/grupo-a/memberships/student-username" \
-f role="member"

9. Official docs​


If you want, next we can add a small scripts/teams.sh helper (create teams, add members from a CSV, sync repo access) tailored to ELT73A-S22-2026-2.

Restrict repository visibility to specific teams in a GitHub organization​

1. Set the organization base permission to No permission (critical)​

This prevents every organization member from automatically seeing or accessing private repositories.

  1. Go to the organization → Settings.
  2. In the left sidebar, under Access, click Member privileges.
  3. Under Base permissions, select No permission.
  4. Save the changes.

With this setting, members only see repositories to which they (or their teams) have been explicitly granted access.

2. Make every group repository Private​

  • Public or Internal repositories are visible more widely.
  • For each labXX-grupo-Y and proyecto-grupo-Y repository:
    • Go to the repository → Settings → General → Danger Zone.
    • Click Change visibility → Make private.

(Organization owners can also restrict who is allowed to change visibility under Member privileges → Repository visibility change.)

3. Grant access only to the matching team​

For each group repository:

  1. Go to the repository → Settings → Collaborators and teams (or Access → Collaborators & teams).
  2. Click Add teams.
  3. Search for and select the matching team (e.g. Grupo-A for lab00-grupo-a).
  4. Choose the appropriate role:
    • Write — typical for students who need to push code.
    • Maintain or Admin — only if the group needs higher privileges.
  5. Confirm.

Do not add other groups or a broad “all students” team to that repository.

You can also manage this from the team side:

  • Organization → Teams → select the team → Repositories tab → add the matching repositories with the desired permission.

4. Handle templates separately​

  • labXX-template and proyecto-template are usually kept private and given Read (or Write) access to an instructors/staff team, or to all groups if students need to see the starter code.
  • Alternatively, leave templates accessible only to instructors and have students create their group repos from the template (or use GitHub Classroom / scripts).
  • Secret teams: Make the student groups Secret teams (Teams → select team → Change visibility → Secret). Secret teams are only visible to their members and organization owners.
  • Avoid nested teams unless you intentionally want inheritance.
  • Prefer granting access via teams rather than individual users.
  • Organization owners always retain full access (this is by design).
  • Regularly audit access: Repository → Settings → Collaborators and teams.

Summary of the effective model​

SettingRecommended valueEffect
Base permissionsNo permissionMembers see nothing by default
Group repos visibilityPrivateNot publicly visible
Access grantsOnly the matching teamlab00-grupo-a → only Grupo-A
TemplatesPrivate + controlled accessSeparate policy

After these steps, a member of Grupo-A will only see (and be able to access) the repositories explicitly shared with Grupo-A. Members of other groups will not see those repositories at all.

If you need to do this at scale (many labs × many groups), the same rules can be applied via the GitHub CLI (gh), the REST/GraphQL API, or automation scripts. Let me know if you want example commands or a script for that.