Skip to content

sudokoi/github-secrets

Repository files navigation

github-secrets

codecov CI

A command-line tool for securely updating GitHub repository secrets across multiple repositories. Built with Rust for performance and security.

Features

  • Multi-repository support: Update secrets across multiple repositories in a single run
  • Interactive selection: Choose specific repositories or select all at once
  • Secure encryption: Uses NaCl sealed box encryption (pure Rust, no system dependencies)
  • XDG Config Directory support: Automatically finds config and .env files in XDG config directory
  • Confirmation prompts: Shows last update date and asks for confirmation before overwriting existing secrets
  • Error handling: Continues processing on errors and provides retry functionality
  • Detailed summaries: Per-repository breakdown and overall operation statistics
  • Comprehensive test coverage: Extensive test suite with unit, integration, and edge case tests

Installation

Prerequisites

  • Rust 1.91.1 or later
  • A GitHub Personal Access Token with repo (for private repos) or public_repo (for public repos) permissions

Build from Source

git clone <repository-url>
cd github-secrets
cargo build --release

The binary will be available at target/release/github-secrets.

Usage

Initial Setup

The tool supports multiple locations for configuration files, following the XDG Base Directory specification:

Configuration File Locations (priority order):

  1. XDG Config Directory (recommended for system-wide setup):

    • $XDG_CONFIG_HOME/github-secrets/config.toml (if XDG_CONFIG_HOME is set)
    • ~/.config/github-secrets/config.toml (default XDG location)
    • $XDG_CONFIG_HOME/github-secrets/.env (if XDG_CONFIG_HOME is set)
    • ~/.config/github-secrets/.env (default XDG location)
  2. Current Directory (fallback):

    • ./config.toml
    • ./.env
  3. Environment Variable Override:

    • CONFIG_PATH environment variable (if set, takes highest priority)

Setup Options:

Option 1: XDG Config Directory (Recommended)

# Create XDG config directory
mkdir -p ~/.config/github-secrets

# Create .env file
cat > ~/.config/github-secrets/.env << EOF
GITHUB_TOKEN=your_github_token_here
XDG_CONFIG_HOME=$HOME/.config  # Optional: explicitly set XDG_CONFIG_HOME
EOF

# Create config.toml file
cat > ~/.config/github-secrets/config.toml << EOF
[[repositories]]
owner = "your_github_username"
name = "your_repository_name"
alias = "My Main Repo"  # Optional friendly name

[[repositories]]
owner = "your_github_username"
name = "another_repository"
alias = "Secondary Repo"  # Optional friendly name
EOF

Option 2: Current Directory (Simple)

  1. Create a .env file in the project root:
GITHUB_TOKEN=your_github_token_here
  1. Create a config.toml file (copy from config.example.toml):
[[repositories]]
owner = "your_github_username"
name = "your_repository_name"
alias = "My Main Repo"  # Optional friendly name

[[repositories]]
owner = "your_github_username"
name = "another_repository"
alias = "Secondary Repo"  # Optional friendly name

Running the Tool

cargo run
# or if installed:
github-secrets

Interactive Configuration

You can manage your repositories directly through the interactive configuration dashboard:

github-secrets config

Dashboard Features:

  • Recall: View your list of configured repositories
  • Add: Press a to add a new repository
  • Edit: Press e or Enter on a selected repository to edit details
  • Delete: Press d to remove a repository
  • Navigation: Use Up/Down arrows to scroll
  • Validation: Owner and Name fields strictly accept alphanumeric characters, underscores, and hyphens.

Key Bindings:

  • /: Navigate list
  • a: Add repository
  • e / Enter: Edit repository
  • d: Delete repository
  • q / Esc: Save and Quit dashboard

Workflow

  1. Select repositories: Choose one or more repositories from the interactive menu, or select "Select All" to update all repositories
  2. Enter secrets: Input key-value pairs interactively
    • Press ESC to finish entering secrets (requires confirmation)
    • Empty keys or values are skipped
  3. Confirm overwrites: If a secret already exists, you'll be shown the last update date and asked for confirmation
    • Press y or Y to confirm (no Enter required)
    • Press N, Enter, or ESC to skip (no Enter required)
  4. Review summary: See overall statistics and per-repository breakdown
  5. Retry failed operations: Option to retry any failed secret updates

Environment Variables

  • GITHUB_TOKEN: Required. Your GitHub Personal Access Token (can be set in .env file)
  • CONFIG_PATH: Optional. Path to config file (overrides default search locations)
  • XDG_CONFIG_HOME: Optional. Custom XDG config directory (defaults to ~/.config if not set)

Example Session

Select repositories to update secrets for:
> [x] Select All
  [ ] My Main Repo (user/repo1)
  [ ] Secondary Repo (user/repo2)

Selected all 2 repositories:
  - My Main Repo (user/repo1)
  - Secondary Repo (user/repo2)

Enter secret key-value pairs. Press ESC to finish.
Secret key (or ESC to finish): API_KEY
Secret value: sk_live_abc123...
Secret pair added.

Secret key (or ESC to finish): [ESC]
Finish entering secrets? (y/N): y

Processing 1 secret(s) across 2 repository/repositories...

============================================================
Repository: My Main Repo (user/repo1)
============================================================
✓ Successfully updated secret 'API_KEY' in My Main Repo (user/repo1)

============================================================
Repository: Secondary Repo (user/repo2)
============================================================
✓ Successfully updated secret 'API_KEY' in Secondary Repo (user/repo2)

============================================================
Overall Summary
============================================================
Total operations: 2
Successful: 2
Failed: 0

Per-repository breakdown:
  My Main Repo (user/repo1): 1 successful, 0 failed
  Secondary Repo (user/repo2): 1 successful, 0 failed

Local Development Setup

Requirements

  • Rust toolchain (install via rustup)
  • Git

Setup Steps

  1. Clone the repository:
git clone <repository-url>
cd github-secrets
  1. Install dependencies:
cargo build
  1. Set up environment (choose one):

Option A: XDG Config Directory

mkdir -p ~/.config/github-secrets
cp .env.example ~/.config/github-secrets/.env
# Edit ~/.config/github-secrets/.env and add your GITHUB_TOKEN

Option B: Current Directory

cp .env.example .env
# Edit .env and add your GITHUB_TOKEN
  1. Create config file (choose one):

Option A: XDG Config Directory

cp config.example.toml ~/.config/github-secrets/config.toml
# Edit ~/.config/github-secrets/config.toml with your repository details

Option B: Current Directory

cp config.example.toml config.toml
# Edit config.toml with your repository details
  1. Run the tool:
cargo run

Running Tests

cargo test

Building for Release

cargo build --release

Code Formatting

cargo fmt

Linting

cargo clippy

Project Structure

github-secrets/
├── src/
│   ├── main.rs          # Entry point and orchestration
│   ├── config.rs        # Configuration file parsing
│   ├── github.rs        # GitHub API client and encryption
│   ├── prompt.rs        # Interactive user prompts
│   └── paths.rs         # XDG config directory and file path resolution
├── Cargo.toml           # Project dependencies
├── config.example.toml  # Example configuration
├── .env.example         # Example environment variables
└── README.md            # This file

Security

  • Secrets are encrypted using NaCl box encryption before being sent to GitHub
  • All encryption is done in pure Rust (no system dependencies)
  • GitHub token is read from environment variables, never hardcoded
  • Secret values are never logged or displayed after input

License

This project is licensed under the MIT License - see the LICENSE file for details.

Test Coverage

This project maintains comprehensive test coverage. Coverage reports are automatically generated on every commit and can be viewed at Codecov.

Running Coverage Locally

To generate a coverage report locally, install cargo-tarpaulin and run:

cargo install cargo-tarpaulin
cargo tarpaulin --out Html --output-dir coverage

This will generate an HTML coverage report in the coverage directory that you can open in your browser.

Coverage Statistics

  • Total Tests: 63 tests (26 unit + 11 edge cases + 3 integration + 14 GitHub API + 8 TUI + 1 doc test)
  • Coverage Reports: Automatically generated on every push to main and develop branches
  • Coverage Badge: Auto-updates in the README based on the latest coverage report

Changelog

See CHANGELOG.md for a detailed list of changes, including breaking changes, new features, and bug fixes.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Commit Message Format

This project uses Conventional Commits for automatic changelog generation. Please format your commit messages as follows:

  • feat: - A new feature
  • fix: - A bug fix
  • chore: - Changes to build process or auxiliary tools
  • breaking: or feat!: - A breaking change
  • docs: - Documentation only changes
  • style: - Code style changes (formatting, etc.)
  • refactor: - Code refactoring
  • test: - Adding or updating tests
  • perf: - Performance improvements

Examples:

  • feat: add support for multiple repositories
  • fix: handle empty config file gracefully
  • chore: update dependencies
  • breaking: change config file format

About

CLI tool for updating github secrets in multiple repos at once

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages