Receber por email
← Voltar para o catálogo

accessing-github-repos

Acesso a repositórios GitHub em ambientes conteinerizados usando a API REST e detecção de credenciais. Utilize quando o git clone falhar, ou para acessar repositórios privados/escrever arquivos via API.

125estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add oaustegard/claude-skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/accessing-github-repos/svg)](https://www.skillteca.com.br/skills/accessing-github-repos)

Alerta por categoria

Receba novas skills de Escrita e Conteúdo toda segunda

1 email curto, só com as skills novas de Escrita e Conteúdo. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Accessing GitHub Repositories

Git clone is blocked in containerized AI environments (egress proxy rejects CONNECT tunnel), but full repository access is available via GitHub REST API and raw file URLs.

Quick Start

Public Repos (no setup needed)

# Individual file via raw URL
curl -sL "https://raw.githubusercontent.com/OWNER/REPO/BRANCH/path/file"

# Directory tree via API
curl -sL "https://api.github.com/repos/OWNER/REPO/git/trees/BRANCH?recursive=1"

Private Repos or Write Access

Requires GitHub Personal Access Token (PAT). See Setup section below.

Setup

Credential Configuration

The skill automatically detects PATs from environment variables or project files:

Environment Variables (checked in order):

  • GITHUB_PAT
  • GH_PAT
  • GITHUB_TOKEN
  • GH_TOKEN

Project Files (Claude.ai):

  • /mnt/project/.env
  • /mnt/project/github.env

Format:

GITHUB_PAT=github_pat_11AAAAAA...

Creating a GitHub PAT

  1. GitHub → Settings → Developer settings → Fine-grained tokens
  2. Create token scoped to needed repositories
  3. Set permissions:
  4. Contents: Read - for private repo access
  5. Contents: Write - for pushing files
  6. Issues: Write - for issue management
  7. Pull requests: Write - for creating PRs

Network Access (Claude.ai Projects)

Add to network allowlist:

  • api.github.com
  • raw.githubusercontent.com

Capabilities by Auth Level

| Capability | No PAT (public only) | PAT (read) | PAT (write) | |------------|---------------------|------------|-------------| | Fetch public files | ✅ | ✅ | ✅ | | Fetch private files | ❌ | ✅ | ✅ | | Download tarball | ✅ public | ✅ | ✅ | | Create/update files | ❌ | ❌ | ✅ | | Create branches | ❌ | ❌ | ✅ | | Manage issues | ❌ | ❌ | ✅ | | Create PRs | ❌ | ❌ | ✅ |

Python Helper Functions

Credential Detection

import os

def get_github_auth():
    """Returns (token, source) or (None, None)"""
    # Check environment variables
    for var in ['GITHUB_PAT', 'GH_PAT', 'GITHUB_TOKEN', 'GH_TOKEN']:
        if token := os.environ.get(var):
            return token, var

    # Check project .env files
    env_paths = ['/mnt/project/.env', '/mnt/project/github.env']
    for path in env_paths:
        try:
            with open(path) as f:
                for line in f:
                    if '=' in line and not line.startswith('#'):
                        key, val = line.strip().split('=', 1)
                        if key in ['GITHUB_PAT', 'GH_PAT', 'GITHUB_TOKEN']:
                            return val.strip(), f'{path}:{key}'
        except FileNotFoundError:
            continue

    return None, None

Fetch Single File

import base64
import urllib.request
import json

def fetch_file(owner: str, repo: str, path: str, ref: str = 'main', token: str = None) -> str:
    """Fetch single file. Uses API if token provided, raw URL otherwise."""
    if token:
        # Use API (works for private repos)
        url = f'https://api.github.com/repos/{owner}/{repo}/contents/{path}?ref={ref}'
        req = urllib.request.Request(url, headers={
            'Authorization': f'Bearer {token}',
            'Accept': 'application/vnd.github+json'
        })
        with urllib.request.urlopen(req) as resp:
            data = json.load(resp)
            return base64.b64decode(data['content']).decode()
    else:
        # Use raw URL (public repos only)
        url = f'https://raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}'
        with urllib.request.urlopen(url) as resp:
            return resp.read().decode()

Fetch Repository Tarball

def fetch_repo_tarball(owner: str, repo: str, ref: str = 'main', token: str = None) -> bytes:
    """Download full repo as tarball. Requires token for private repos."""
    url = f'https://api.github.com/repos/{owner}/{repo}/tarball/{ref}'
    headers = {'Accept': 'application/vnd.github+json'}
    if token:
        headers['Authorization'] = f'Bearer {token}'

    req = urllib.request.Request(url, headers=headers)
    with urllib.request.urlopen(req) as resp:
        return resp.read()

# Usage:
tarball = fetch_repo_tarball('owner', 'repo', 'main', token)
with open('/tmp/repo.tar.gz', 'wb') as f:
    f.write(tarball)
# Extract: tar -xzf /tmp/repo.tar.gz

Create or Update File

def push_file(owner: str, repo: str, path: str, content: str,
              message: str, token: str, sha: str = None) -> dict:
    """Create/update file via API. Returns commit info.

    Args:
        sha: Required when updating existing file (get via contents API)
    """
    url = f'https://api.github.com/repos/{owner}/{repo}/contents/{path}'

    payload = {
        'message': message,
        'content': base64.b64encode(content.encode()).decode()
    }
    if sha:  # Update existing file
        payload['sha'] = sha

    req = urllib.request.Request(url,
        data=json.dumps(payload).encode(),
        headers={
            'Authorization': f'Bearer {token}',
            'Accept': 'application/vnd.github+json',
            'Content-Type': 'application/json'
        },
        method='PUT')

    with urllib.request.urlopen(req) as resp:
        return json.load(resp)

Get File SHA (for updates)

def get_file_sha(owner: str, repo: str, path: str, token: str, ref: str = 'main') -> str:
    """Get file SHA needed for updates."""
    url = f'https://api.github.com/repos/{owner}/{repo}/contents/{path}?ref={ref}'
    req = urllib.request.Request(url, headers={
        'Authorization': f'Bearer {token}',
        'Accept': 'application/vnd.github+json'
    })
    with urllib.request.urlopen(req) as resp:
        data = json.load(resp)
        return data['sha']

Bash Examples

Fetch Public File

curl -sL "https://raw.githubusercontent.com/owner/repo/main/path/file.py"

Fetch Private File (with PAT)

curl -H "Authorization: Bearer $GITHUB_PAT" \
     -H "Accept: application/vnd.github+json" \
     "https://api.github.com/repos/owner/repo/contents/path/file.py" | \
     python3 -c "import sys,json,base64; print(base64.b64decode(json.load(sys.stdin)['content']).decode())"

Download Repo Tarball

# Public repo
curl -sL "https://api.github.com/repos/owner/repo/tarball/main" -o repo.tar.gz

# Private repo
curl -sL -H "Authorization: Bearer $GITHUB_PAT" \
     "https://api.github.com/repos/owner/repo/tarball/main" -o repo.tar.gz
tar -xzf repo.tar.gz

Create/Update File

# Encode content
CONTENT=$(cat file.txt | base64 -w0)

# Push (new file)
curl -X PUT \
     -H "Authorization: Bearer $GITHUB_PAT" \
     -H "Accept: application/vnd.github+json" \
     "https://api.github.com/repos/owner/repo/contents/path/file.txt" \
     -d "{\"message\":\"Add file\",\"content\":\"$CONTENT\"}"

# Push (update existing - need SHA first)
SHA=$(curl -s -H "Authorization: Bearer $GITHUB_PAT" \
           "https://api.github.com/repos/owner/repo/contents/path/file.txt" | \
           python3 -c "import sys,json; print(json.load(sys.stdin)['sha'])")

curl -X PUT \
     -H "Authorization: Bearer $GITHUB_PAT" \
     -H "Accept: application/vnd.github+json" \
     "https://api.github.com/repos/owner/repo/contents/path/file.txt" \
     -d "{\"message\":\"Update file\",\"content\":\"$CONTENT\",\"sha\":\"$SHA\"}"

List Directory Tree

curl -sL "https://api.github.com/repos/owner/repo/git/trees/main?recursive=1" | \
  python3 -c "import json, sys; [print(f['path']) for f in json.load(sys.stdin)['tree'] if f['type']=='blob']"

Why git clone Doesn't Work

The container's egress proxy blocks git protocol operations:

  • HTTPS clone: Proxy returns 401 on CONNECT tunnel
  • SSH: No ssh binary in container
  • git:// protocol: DNS resolution blocked

The GitHub REST API uses standard HTTPS and routes through the proxy normally.

Do Not

  • Never attempt git clone (wastes time, always fails)
Compartilhar X LinkedIn