Github Repo Management — Clone/create/fork repos; manage remotes, releases
Github Repo Management
Section titled “Github Repo Management”Clone/create/fork repos; manage remotes, releases.
Skill metadata
Section titled “Skill metadata”| Source | Bundled (installed by default) |
| Path | skills/github/github-repo-management |
| Version | 1.1.0 |
| Author | Hermes Agent |
| License | MIT |
| Tags | GitHub, Repositories, Git, Releases, Secrets, Configuration |
| Related skills | github-auth, github-pr-workflow, github-issues |
Reference: full SKILL.md
Section titled “Reference: full SKILL.md”The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active.
GitHub Repository Management
Section titled “GitHub Repository Management”Create, clone, fork, configure, and manage GitHub repositories. Each section shows gh first, then the git + curl fallback.
Prerequisites
Section titled “Prerequisites”- Authenticated with GitHub (see
github-authskill)
if command -v gh &>/dev/null && gh auth status &>/dev/null; then AUTH="gh"else AUTH="git" if [ -z "$GITHUB_TOKEN" ]; then if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r') elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|') fi fifi
# Get your GitHub username (needed for several operations)if [ "$AUTH" = "gh" ]; then GH_USER=$(gh api user --jq '.login')else GH_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user | python3 -c "import sys,json; print(json.load(sys.stdin)['login'])")fiIf you’re inside a repo already:
REMOTE_URL=$(git remote get-url origin)OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)1. Cloning Repositories
Section titled “1. Cloning Repositories”Cloning is pure git — works identically either way:
# Clone via HTTPS (works with credential helper or token-embedded URL)git clone https://github.com/owner/repo-name.git
# Clone into a specific directorygit clone https://github.com/owner/repo-name.git ./my-local-dir
# Shallow clone (faster for large repos)git clone --depth 1 https://github.com/owner/repo-name.git
# Clone a specific branchgit clone --branch develop https://github.com/owner/repo-name.git
# Clone via SSH (if SSH is configured)git clone git@github.com:owner/repo-name.gitWith gh (shorthand):
gh repo clone owner/repo-namegh repo clone owner/repo-name -- --depth 12. Creating Repositories
Section titled “2. Creating Repositories”With gh:
# Create a public repo and clone itgh repo create my-new-project --public --clone
# Private, with description and licensegh repo create my-new-project --private --description "A useful tool" --license MIT --clone
# Under an organizationgh repo create my-org/my-new-project --public --clone
# From existing local directorycd /path/to/existing/projectgh repo create my-project --source . --public --pushWith git + curl:
# Create the remote repo via APIcurl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/user/repos \ -d '{ "name": "my-new-project", "description": "A useful tool", "private": false, "auto_init": true, "license_template": "mit" }'
# Clone itgit clone https://github.com/$GH_USER/my-new-project.gitcd my-new-project
# -- OR -- push an existing local directory to the new repocd /path/to/existing/projectgit initgit add .git commit -m "Initial commit"git remote add origin https://github.com/$GH_USER/my-new-project.gitgit push -u origin mainTo create under an organization:
curl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/orgs/my-org/repos \ -d '{"name": "my-new-project", "private": false}'From a Template
Section titled “From a Template”With gh:
gh repo create my-new-app --template owner/template-repo --public --cloneWith curl:
curl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/owner/template-repo/generate \ -d '{"owner": "'"$GH_USER"'", "name": "my-new-app", "private": false}'3. Forking Repositories
Section titled “3. Forking Repositories”With gh:
gh repo fork owner/repo-name --cloneWith git + curl:
# Create the fork via APIcurl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/owner/repo-name/forks
# Wait a moment for GitHub to create it, then clonesleep 3git clone https://github.com/$GH_USER/repo-name.gitcd repo-name
# Add the original repo as "upstream" remotegit remote add upstream https://github.com/owner/repo-name.gitKeeping a Fork in Sync
Section titled “Keeping a Fork in Sync”# Pure git — works everywheregit fetch upstreamgit checkout maingit merge upstream/maingit push origin mainWith gh (shortcut):
gh repo sync $GH_USER/repo-name4. Repository Information
Section titled “4. Repository Information”With gh:
gh repo view owner/repo-namegh repo list --limit 20gh search repos "machine learning" --language python --sort starsWith curl:
# View repo detailscurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO \ | python3 -c "import sys, jsonr = json.load(sys.stdin)print(f\"Name: {r['full_name']}\")print(f\"Description: {r['description']}\")print(f\"Stars: {r['stargazers_count']} Forks: {r['forks_count']}\")print(f\"Default branch: {r['default_branch']}\")print(f\"Language: {r['language']}\")"
# List your reposcurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/user/repos?per_page=20&sort=updated" \ | python3 -c "import sys, jsonfor r in json.load(sys.stdin): vis = 'private' if r['private'] else 'public' print(f\" {r['full_name']:40} {vis:8} {r.get('language', ''):10} ★{r['stargazers_count']}\")"
# Search reposcurl -s \ "https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10" \ | python3 -c "import sys, jsonfor r in json.load(sys.stdin)['items']: print(f\" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}\")"5. Repository Settings
Section titled “5. Repository Settings”With gh:
gh repo edit --description "Updated description" --visibility publicgh repo edit --enable-wiki=false --enable-issues=truegh repo edit --default-branch maingh repo edit --add-topic "machine-learning,python"gh repo edit --enable-auto-mergeWith curl:
curl -s -X PATCH \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO \ -d '{ "description": "Updated description", "has_wiki": false, "has_issues": true, "allow_auto_merge": true }'
# Update topicscurl -s -X PUT \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github.mercy-preview+json" \ https://api.github.com/repos/$OWNER/$REPO/topics \ -d '{"names": ["machine-learning", "python", "automation"]}'6. Branch Protection
Section titled “6. Branch Protection”# View current protectioncurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/branches/main/protection
# Set up branch protectioncurl -s -X PUT \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/branches/main/protection \ -d '{ "required_status_checks": { "strict": true, "contexts": ["ci/test", "ci/lint"] }, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 1 }, "restrictions": null }'7. Secrets Management (GitHub Actions)
Section titled “7. Secrets Management (GitHub Actions)”With gh:
gh secret set API_KEY --body "your-secret-value"gh secret set SSH_KEY < ~/.ssh/id_rsagh secret listgh secret delete API_KEYWith curl:
Secrets require encryption with the repo’s public key — more involved via API:
# Get the repo's public key for encrypting secretscurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/secrets/public-key
# Encrypt and set (requires Python with PyNaCl)python3 -c "from base64 import b64encodefrom nacl import encoding, publicimport json, sys
# Get the public keykey_id = '<key_id_from_above>'public_key = '<base64_key_from_above>'
# Encryptsealed = public.SealedBox( public.PublicKey(public_key.encode('utf-8'), encoding.Base64Encoder)).encrypt('your-secret-value'.encode('utf-8'))print(json.dumps({ 'encrypted_value': b64encode(sealed).decode('utf-8'), 'key_id': key_id}))"
# Then PUT the encrypted secretcurl -s -X PUT \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/secrets/API_KEY \ -d '<output from python script above>'
# List secrets (names only, values hidden)curl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/secrets \ | python3 -c "import sys, jsonfor s in json.load(sys.stdin)['secrets']: print(f\" {s['name']:30} updated: {s['updated_at']}\")"Note: For secrets, gh secret set is dramatically simpler. If setting secrets is needed and gh isn’t available, recommend installing it for just that operation.
8. Releases
Section titled “8. Releases”With gh:
gh release create v1.0.0 --title "v1.0.0" --generate-notesgh release create v2.0.0-rc1 --draft --prerelease --generate-notesgh release create v1.0.0 ./dist/binary --title "v1.0.0" --notes "Release notes"gh release listgh release download v1.0.0 --dir ./downloadsWith curl:
# Create a releasecurl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/releases \ -d '{ "tag_name": "v1.0.0", "name": "v1.0.0", "body": "## Changelog\n- Feature A\n- Bug fix B", "draft": false, "prerelease": false, "generate_release_notes": true }'
# List releasescurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/releases \ | python3 -c "import sys, jsonfor r in json.load(sys.stdin): tag = r.get('tag_name', 'no tag') print(f\" {tag:15} {r['name']:30} {'draft' if r['draft'] else 'published'}\")"
# Upload a release asset (binary file)RELEASE_ID=<id_from_create_response>curl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Content-Type: application/octet-stream" \ "https://uploads.github.com/repos/$OWNER/$REPO/releases/$RELEASE_ID/assets?name=binary-amd64" \ --data-binary @./dist/binary-amd649. GitHub Actions Workflows
Section titled “9. GitHub Actions Workflows”With gh:
gh workflow listgh run list --limit 10gh run view <RUN_ID>gh run view <RUN_ID> --log-failedgh run rerun <RUN_ID>gh run rerun <RUN_ID> --failedgh workflow run ci.yml --ref maingh workflow run deploy.yml -f environment=stagingWith curl:
# List workflowscurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/workflows \ | python3 -c "import sys, jsonfor w in json.load(sys.stdin)['workflows']: print(f\" {w['id']:10} {w['name']:30} {w['state']}\")"
# List recent runscurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10" \ | python3 -c "import sys, jsonfor r in json.load(sys.stdin)['workflow_runs']: print(f\" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}\")"
# Download failed run logsRUN_ID=<run_id>curl -s -L \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \ -o /tmp/ci-logs.zipcd /tmp && unzip -o ci-logs.zip -d ci-logs
# Re-run a failed workflowcurl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun
# Re-run only failed jobscurl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs
# Trigger a workflow manually (workflow_dispatch)WORKFLOW_ID=<workflow_id_or_filename>curl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/dispatches \ -d '{"ref": "main", "inputs": {"environment": "staging"}}'10. Gists
Section titled “10. Gists”With gh:
gh gist create script.py --public --desc "Useful script"gh gist listWith curl:
# Create a gistcurl -s -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/gists \ -d '{ "description": "Useful script", "public": true, "files": { "script.py": {"content": "print(\"hello\")"} } }'
# List your gistscurl -s \ -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/gists \ | python3 -c "import sys, jsonfor g in json.load(sys.stdin): files = ', '.join(g['files'].keys()) print(f\" {g['id']} {g['description'] or '(no desc)':40} {files}\")"Quick Reference Table
Section titled “Quick Reference Table”| Action | gh | git + curl |
|---|---|---|
| Clone | gh repo clone o/r | git clone https://github.com/o/r.git |
| Create repo | gh repo create name --public | curl POST /user/repos |
| Fork | gh repo fork o/r --clone | curl POST /repos/o/r/forks + git clone |
| Repo info | gh repo view o/r | curl GET /repos/o/r |
| Edit settings | gh repo edit --... | curl PATCH /repos/o/r |
| Create release | gh release create v1.0 | curl POST /repos/o/r/releases |
| List workflows | gh workflow list | curl GET /repos/o/r/actions/workflows |
| Rerun CI | gh run rerun ID | curl POST /repos/o/r/actions/runs/ID/rerun |
| Set secret | gh secret set KEY | curl PUT /repos/o/r/actions/secrets/KEY (+ encryption) |