The github module provides integration with GitHub Releases API for checking available updates and downloading release assets.
This module enables tsupdate to query GitHub releases, find applicable updates, and resolve download URLs for both public and private repositories.
GitHub authentication is obtained from two sources (in order of priority):
GH_TOKENenvironment variable - Personal access token- GitHub CLI - Token from
gh auth tokencommand
For private repositories, the token must have repo scope permissions.
initialize_github_token(): Load token at program start (called once in cli.py).
get_github_token(): Retrieve the loaded token.
parse_github_repo_url(support_url): Extract owner/repo from GitHub URLs.
parse_github_release_url(url): Parse release URLs to extract owner, repo, tag, and asset name.
resolve_github_release_url(url): Convert release URL to authenticated API endpoint.
fetch_releases(owner, repo, include_prereleases): Get list of releases from repository.
find_latest_image(releases): Find latest OS image in releases.
find_applicable_batch_update(releases, current_version, max_releases): Find incremental update matching current version.
Matches files with image extensions:
.img.gz(gzip compressed).xz(xz compressed).zip(zip archive)
Selects the largest file among candidates.
Pattern: tsOS-{variant}-arm64-update-{current_version}-to-{next_version}.tar
Examples:
tsOS-base-arm64-update-2025.12.1-to-2025.12.2.tartsOS-pro-arm64-update-2025.12.1-to-2025.12.2.tar.gz
from tsupdate.status import read_booted_os_release
from tsupdate.github import parse_github_repo_url, fetch_releases, find_latest_image, find_applicable_batch_update
# Get current version
os_release = read_booted_os_release()
version_id = os_release.version_id
support_url = os_release.get("SUPPORT_URL")
# Parse repository
owner, repo = parse_github_repo_url(support_url)
# Fetch releases
releases = fetch_releases(owner, repo, include_prereleases=False)
# Find latest image
image_url = find_latest_image(releases)
print(f"Latest image: {image_url}")
# Find applicable batch update
batch_url = find_applicable_batch_update(releases, version_id, max_releases=5)
print(f"Next update: {batch_url}")from tsupdate.github import resolve_github_release_url
# Public URL from release page
url = "https://github.com/owner/repo/releases/download/v1.0/tsos.img.gz"
# Resolve to authenticated API endpoint (uses GH_TOKEN)
api_url = resolve_github_release_url(url)
# Use api_url with utils.download_file() for authenticated downloadThe check command uses this module:
# Check for updates using SUPPORT_URL from /etc/os-release
tsupdate check
# Include pre-releases
tsupdate check --pre
# Check more releases for batch updates (default: 5)
tsupdate check --max-releases 10
# Override repository URL
tsupdate check --github-url https://github.com/owner/repoSet GH_TOKEN for GitHub authentication:
# Export token
export GH_TOKEN="ghp_..."
# Check for updates (uses token)
tsupdate check
# Apply update from private repository (uses token)
sudo tsupdate apply https://github.com/owner/private-repo/releases/download/v1.0/update.tarOr use GitHub CLI:
# Authenticate with GitHub CLI
gh auth login
# Check for updates (uses gh token automatically)
tsupdate check- 60 requests per hour per IP address
- Sufficient for occasional checks
- 5,000 requests per hour per user
- Recommended for automated systems
The module logs rate limit information in verbose mode:
tsupdate -v check404 Not Found:
- Repository doesn't exist or is private
- For private repos, ensure
GH_TOKENis set withreposcope
403 Forbidden:
- Rate limit exceeded
- Token lacks required permissions
Network Errors:
- Connection timeout
- DNS resolution failure
The module provides helpful error messages:
Repository not found: owner/repo
If this is a private repository, set GH_TOKEN environment variable with a token that has 'repo' scope.
This module uses the PyGithub library for GitHub API access. It provides:
- Automatic pagination
- Rate limit handling
- Response caching
- Type safety
The _create_github_client() function handles authentication and validation:
- Creates authenticated client if token available
- Verifies token by checking rate limit
- Logs authentication status in verbose mode
The _get_assets_from_release() function optimizes API usage:
- Tries to use raw_data first (no API call)
- Falls back to API call if needed
- Returns consistent asset information format
For private repositories:
-
Create personal access token:
- Go to GitHub Settings → Developer settings → Personal access tokens
- Generate token with
reposcope - Save token securely
-
Set environment variable:
export GH_TOKEN="ghp_your_token_here"
-
Use tsupdate commands normally:
tsupdate check sudo tsupdate apply https://github.com/owner/private-repo/releases/download/v1.0/update.tar
- Token storage: Never commit tokens to version control
- Token scope: Use minimal required scope (
repofor private repos) - Token rotation: Regularly rotate tokens
- Token expiration: Use tokens with expiration dates
- CLI integration: GitHub CLI stores tokens securely
The module works with VERSION_ID format: YYYY.MM.N
Examples:
2025.12.1- First release in December 20252025.12.2- Second release in December 2025
Batch update matching is strict - requires exact version match.