github-repo-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGitHub Repository Management
GitHub仓库管理
Create, clone, fork, configure, and manage GitHub repositories. Each section shows first, then the + fallback.
ghgitcurl创建、克隆、复刻、配置和管理GitHub仓库。每个章节先展示命令,再给出 + 的替代方案。
ghgitcurlPrerequisites
前置条件
- Authenticated with GitHub (see skill)
github-auth
- 已通过GitHub身份验证(参考技能)
github-auth
Setup
环境配置
bash
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
fi
fibash
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
fi
fiGet your GitHub username (needed for several operations)
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'])")
fi
If you're inside a repo already:
```bash
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)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'])")
fi
如果你已经在某个仓库目录下:
```bash
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
1. 克隆仓库
Cloning is pure — works identically either way:
gitbash
undefined克隆操作完全使用命令——两种方式效果一致:
gitbash
undefinedClone via HTTPS (works with credential helper or token-embedded URL)
Clone via HTTPS (works with credential helper or token-embedded URL)
git clone https://github.com/owner/repo-name.git
git clone https://github.com/owner/repo-name.git
Clone into a specific directory
Clone into a specific directory
git clone https://github.com/owner/repo-name.git ./my-local-dir
git clone https://github.com/owner/repo-name.git ./my-local-dir
Shallow clone (faster for large repos)
Shallow clone (faster for large repos)
git clone --depth 1 https://github.com/owner/repo-name.git
git clone --depth 1 https://github.com/owner/repo-name.git
Clone a specific branch
Clone a specific branch
git clone --branch develop https://github.com/owner/repo-name.git
git clone --branch develop https://github.com/owner/repo-name.git
Clone via SSH (if SSH is configured)
Clone via SSH (if SSH is configured)
git clone git@github.com:owner/repo-name.git
**With gh (shorthand):**
```bash
gh repo clone owner/repo-name
gh repo clone owner/repo-name -- --depth 1git clone git@github.com:owner/repo-name.git
**使用gh(简写方式):**
```bash
gh repo clone owner/repo-name
gh repo clone owner/repo-name -- --depth 12. Creating Repositories
2. 创建仓库
With gh:
bash
undefined使用gh:
bash
undefinedCreate a public repo and clone it
Create a public repo and clone it
gh repo create my-new-project --public --clone
gh repo create my-new-project --public --clone
Private, with description and license
Private, with description and license
gh repo create my-new-project --private --description "A useful tool" --license MIT --clone
gh repo create my-new-project --private --description "A useful tool" --license MIT --clone
Under an organization
Under an organization
gh repo create my-org/my-new-project --public --clone
gh repo create my-org/my-new-project --public --clone
From existing local directory
From existing local directory
cd /path/to/existing/project
gh repo create my-project --source . --public --push
**With git + curl:**
```bashcd /path/to/existing/project
gh repo create my-project --source . --public --push
**使用git + curl:**
```bashCreate the remote repo via API
Create the remote repo via API
curl -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" }'
-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" }'
curl -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" }'
-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 it
Clone it
git clone https://github.com/$GH_USER/my-new-project.git
cd my-new-project
git clone https://github.com/$GH_USER/my-new-project.git
cd my-new-project
-- OR -- push an existing local directory to the new repo
-- OR -- push an existing local directory to the new repo
cd /path/to/existing/project
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/$GH_USER/my-new-project.git
git push -u origin main
To create under an organization:
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/orgs/my-org/repos \
-d '{"name": "my-new-project", "private": false}'cd /path/to/existing/project
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/$GH_USER/my-new-project.git
git push -u origin main
在组织下创建仓库:
```bash
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
从模板创建
With gh:
bash
gh repo create my-new-app --template owner/template-repo --public --cloneWith curl:
bash
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}'使用gh:
bash
gh repo create my-new-app --template owner/template-repo --public --clone使用curl:
bash
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
3. 复刻仓库
With gh:
bash
gh repo fork owner/repo-name --cloneWith git + curl:
bash
undefined使用gh:
bash
gh repo fork owner/repo-name --clone使用git + curl:
bash
undefinedCreate the fork via API
Create the fork via API
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/owner/repo-name/forks
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/owner/repo-name/forks
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/owner/repo-name/forks
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/owner/repo-name/forks
Wait a moment for GitHub to create it, then clone
Wait a moment for GitHub to create it, then clone
sleep 3
git clone https://github.com/$GH_USER/repo-name.git
cd repo-name
sleep 3
git clone https://github.com/$GH_USER/repo-name.git
cd repo-name
Add the original repo as "upstream" remote
Add the original repo as "upstream" remote
git remote add upstream https://github.com/owner/repo-name.git
undefinedgit remote add upstream https://github.com/owner/repo-name.git
undefinedKeeping a Fork in Sync
保持复刻仓库同步
bash
undefinedbash
undefinedPure git — works everywhere
Pure git — works everywhere
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
**With gh (shortcut):**
```bash
gh repo sync $GH_USER/repo-namegit fetch upstream
git checkout main
git merge upstream/main
git push origin main
**使用gh(快捷方式):**
```bash
gh repo sync $GH_USER/repo-name4. Repository Information
4. 仓库信息查询
With gh:
bash
gh repo view owner/repo-name
gh repo list --limit 20
gh search repos "machine learning" --language python --sort starsWith curl:
bash
undefined使用gh:
bash
gh repo view owner/repo-name
gh repo list --limit 20
gh search repos "machine learning" --language python --sort stars使用curl:
bash
undefinedView repo details
View repo details
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO
| python3 -c " import sys, json r = 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']}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO
| python3 -c " import sys, json r = 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']}")"
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO
| python3 -c " import sys, json r = 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']}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO
| python3 -c " import sys, json r = 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 repos
List your repos
curl -s
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/user/repos?per_page=20&sort=updated"
| python3 -c " import sys, json for 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']}")"
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/user/repos?per_page=20&sort=updated"
| python3 -c " import sys, json for 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']}")"
curl -s
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/user/repos?per_page=20&sort=updated"
| python3 -c " import sys, json for 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']}")"
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/user/repos?per_page=20&sort=updated"
| python3 -c " import sys, json for 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 repos
Search repos
curl -s
"https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['items']: print(f" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}")"
"https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['items']: print(f" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}")"
undefinedcurl -s
"https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['items']: print(f" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}")"
"https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['items']: print(f" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}")"
undefined5. Repository Settings
5. 仓库设置
With gh:
bash
gh repo edit --description "Updated description" --visibility public
gh repo edit --enable-wiki=false --enable-issues=true
gh repo edit --default-branch main
gh repo edit --add-topic "machine-learning,python"
gh repo edit --enable-auto-mergeWith curl:
bash
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
}'使用gh:
bash
gh repo edit --description "Updated description" --visibility public
gh repo edit --enable-wiki=false --enable-issues=true
gh repo edit --default-branch main
gh repo edit --add-topic "machine-learning,python"
gh repo edit --enable-auto-merge使用curl:
bash
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 topics
Update topics
curl -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"]}'
-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"]}'
undefinedcurl -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"]}'
-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"]}'
undefined6. Branch Protection
6. 分支保护
bash
undefinedbash
undefinedView current protection
View current protection
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection
Set up branch protection
Set up branch protection
curl -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 }'
-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 }'
undefinedcurl -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 }'
-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 }'
undefined7. Secrets Management (GitHub Actions)
7. Secrets管理(GitHub Actions)
With gh:
bash
gh secret set API_KEY --body "your-secret-value"
gh secret set SSH_KEY < ~/.ssh/id_rsa
gh secret list
gh secret delete API_KEYWith curl:
Secrets require encryption with the repo's public key — more involved via API:
bash
undefined使用gh:
bash
gh secret set API_KEY --body "your-secret-value"
gh secret set SSH_KEY < ~/.ssh/id_rsa
gh secret list
gh secret delete API_KEY使用curl:
Secrets需要使用仓库的公钥加密——通过API操作较为复杂:
bash
undefinedGet the repo's public key for encrypting secrets
Get the repo's public key for encrypting secrets
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/public-key
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/public-key
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/public-key
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/public-key
Encrypt and set (requires Python with PyNaCl)
Encrypt and set (requires Python with PyNaCl)
python3 -c "
from base64 import b64encode
from nacl import encoding, public
import json, sys
python3 -c "
from base64 import b64encode
from nacl import encoding, public
import json, sys
Get the public key
Get the public key
key_id = '<key_id_from_above>'
public_key = '<base64_key_from_above>'
key_id = '<key_id_from_above>'
public_key = '<base64_key_from_above>'
Encrypt
Encrypt
sealed = 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
}))"
sealed = 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 secret
Then PUT the encrypted secret
curl -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>'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/API_KEY
-d '<output from python script above>'
curl -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>'
-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)
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, json for s in json.load(sys.stdin)['secrets']: print(f" {s['name']:30} updated: {s['updated_at']}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets
| python3 -c " import sys, json for 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.curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets
| python3 -c " import sys, json for s in json.load(sys.stdin)['secrets']: print(f" {s['name']:30} updated: {s['updated_at']}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/secrets
| python3 -c " import sys, json for s in json.load(sys.stdin)['secrets']: print(f" {s['name']:30} updated: {s['updated_at']}")"
注意:对于Secrets,`gh secret set`命令要简单得多。如果需要设置Secrets且没有安装gh,建议专门安装gh来执行该操作。8. Releases
8. 版本发布
With gh:
bash
gh release create v1.0.0 --title "v1.0.0" --generate-notes
gh release create v2.0.0-rc1 --draft --prerelease --generate-notes
gh release create v1.0.0 ./dist/binary --title "v1.0.0" --notes "Release notes"
gh release list
gh release download v1.0.0 --dir ./downloadsWith curl:
bash
undefined使用gh:
bash
gh release create v1.0.0 --title "v1.0.0" --generate-notes
gh release create v2.0.0-rc1 --draft --prerelease --generate-notes
gh release create v1.0.0 ./dist/binary --title "v1.0.0" --notes "Release notes"
gh release list
gh release download v1.0.0 --dir ./downloads使用curl:
bash
undefinedCreate a release
Create a release
curl -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 }'
-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 }'
curl -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 }'
-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 releases
List releases
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/releases
| python3 -c " import sys, json for 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'}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/releases
| python3 -c " import sys, json for 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'}")"
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/releases
| python3 -c " import sys, json for 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'}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/releases
| python3 -c " import sys, json for 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)
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-amd64
-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-amd64
undefinedRELEASE_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-amd64
-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-amd64
undefined9. GitHub Actions Workflows
9. GitHub Actions工作流
With gh:
bash
gh workflow list
gh run list --limit 10
gh run view <RUN_ID>
gh run view <RUN_ID> --log-failed
gh run rerun <RUN_ID>
gh run rerun <RUN_ID> --failed
gh workflow run ci.yml --ref main
gh workflow run deploy.yml -f environment=stagingWith curl:
bash
undefined使用gh:
bash
gh workflow list
gh run list --limit 10
gh run view <RUN_ID>
gh run view <RUN_ID> --log-failed
gh run rerun <RUN_ID>
gh run rerun <RUN_ID> --failed
gh workflow run ci.yml --ref main
gh workflow run deploy.yml -f environment=staging使用curl:
bash
undefinedList workflows
List workflows
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/workflows
| python3 -c " import sys, json for w in json.load(sys.stdin)['workflows']: print(f" {w['id']:10} {w['name']:30} {w['state']}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/workflows
| python3 -c " import sys, json for w in json.load(sys.stdin)['workflows']: print(f" {w['id']:10} {w['name']:30} {w['state']}")"
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/workflows
| python3 -c " import sys, json for w in json.load(sys.stdin)['workflows']: print(f" {w['id']:10} {w['name']:30} {w['state']}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/workflows
| python3 -c " import sys, json for w in json.load(sys.stdin)['workflows']: print(f" {w['id']:10} {w['name']:30} {w['state']}")"
List recent runs
List recent runs
curl -s
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['workflow_runs']: print(f" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}")"
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['workflow_runs']: print(f" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}")"
curl -s
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['workflow_runs']: print(f" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}")"
-H "Authorization: token $GITHUB_TOKEN"
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10"
| python3 -c " import sys, json for r in json.load(sys.stdin)['workflow_runs']: print(f" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}")"
Download failed run logs
Download failed run logs
RUN_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.zip cd /tmp && unzip -o ci-logs.zip -d ci-logs
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs
-o /tmp/ci-logs.zip cd /tmp && unzip -o ci-logs.zip -d ci-logs
RUN_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.zip cd /tmp && unzip -o ci-logs.zip -d ci-logs
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs
-o /tmp/ci-logs.zip cd /tmp && unzip -o ci-logs.zip -d ci-logs
Re-run a failed workflow
Re-run a failed workflow
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun
Re-run only failed jobs
Re-run only failed jobs
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs
curl -s -X POST
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs
-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)
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"}}'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/dispatches
-d '{"ref": "main", "inputs": {"environment": "staging"}}'
undefinedWORKFLOW_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"}}'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/dispatches
-d '{"ref": "main", "inputs": {"environment": "staging"}}'
undefined10. Gists
10. Gists管理
With gh:
bash
gh gist create script.py --public --desc "Useful script"
gh gist listWith curl:
bash
undefined使用gh:
bash
gh gist create script.py --public --desc "Useful script"
gh gist list使用curl:
bash
undefinedCreate a gist
Create a gist
curl -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")"} } }'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/gists
-d '{ "description": "Useful script", "public": true, "files": { "script.py": {"content": "print("hello")"} } }'
curl -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")"} } }'
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/gists
-d '{ "description": "Useful script", "public": true, "files": { "script.py": {"content": "print("hello")"} } }'
List your gists
List your gists
curl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/gists
| python3 -c " import sys, json for g in json.load(sys.stdin): files = ', '.join(g['files'].keys()) print(f" {g['id']} {g['description'] or '(no desc)':40} {files}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/gists
| python3 -c " import sys, json for g in json.load(sys.stdin): files = ', '.join(g['files'].keys()) print(f" {g['id']} {g['description'] or '(no desc)':40} {files}")"
undefinedcurl -s
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/gists
| python3 -c " import sys, json for g in json.load(sys.stdin): files = ', '.join(g['files'].keys()) print(f" {g['id']} {g['description'] or '(no desc)':40} {files}")"
-H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/gists
| python3 -c " import sys, json for g in json.load(sys.stdin): files = ', '.join(g['files'].keys()) print(f" {g['id']} {g['description'] or '(no desc)':40} {files}")"
undefinedQuick Reference Table
快速参考表
| Action | gh | git + curl |
|---|---|---|
| Clone | | |
| Create repo | | |
| Fork | | |
| Repo info | | |
| Edit settings | | |
| Create release | | |
| List workflows | | |
| Rerun CI | | |
| Set secret | | |
| 操作 | gh | git + curl |
|---|---|---|
| 克隆 | | |
| 创建仓库 | | |
| 复刻 | | |
| 仓库信息查询 | | |
| 编辑设置 | | |
| 创建版本发布 | | |
| 列出工作流 | | |
| 重新运行CI | | |
| 设置Secret | | |