A powerful CLI tool for synchronizing secrets across Gitea organizations and repositories. This tool enables batch updates of action secrets to multiple Gitea organizations and repositories simultaneously, with support for dry-run mode and SSL verification options.
- 🔐 Batch Secret Management: Sync multiple secrets to organizations and repositories at once
- 🏢 Organization Support: Update secrets for multiple Gitea organizations
- 📁 Repository Support: Update secrets for specific repositories (format:
org/repo) - 🔍 Dry Run Mode: Preview changes without actually updating secrets
- 🔒 SSL Configuration: Option to skip SSL verification for self-hosted Gitea instances
- 📁 Environment File Support: Load configuration from
.envfiles - 📊 Structured Logging: Clear logging with structured output
- 🛡️ Graceful Shutdown: Handle interruption signals gracefully
go install github.com/appleboy/gitea-secret-sync/cmd@latestDownload the latest binary from the releases page.
gitea-secret-sync [options]Options:
-env-file string: Read in a file of environment variables (default: ".env")-version: Show version information and exit
The tool supports two formats for environment variables:
- Direct format:
VARIABLE_NAME=value - Input format:
INPUT_VARIABLE_NAME=value(takes precedence over direct format)
| Variable | Description | Example |
|---|---|---|
GITEA_SERVER |
Gitea server URL | https://gitea.example.com |
GITEA_TOKEN |
Gitea access token | your_gitea_token_here |
SECRETS |
Comma or newline-separated list of secret names to sync | SECRET1,SECRET2,SECRET3 |
| Variable | Description | Default | Example |
|---|---|---|---|
GITEA_SKIP_VERIFY |
Skip SSL certificate verification | false |
true |
ORGS |
Comma or newline-separated list of organizations to update | - | org1,org2,org3 |
REPOS |
Comma or newline-separated list of repositories to update | - | org1/repo1,org2/repo2 |
DRY_RUN |
Enable dry-run mode (preview only) | false |
true |
For each secret name listed in SECRETS, you need to provide the corresponding environment variable:
# If SECRETS=SECRET1,SECRET2,SECRET3
SECRET1=actual_secret_value_1
SECRET2=actual_secret_value_2
SECRET3=actual_secret_value_3The tool supports flexible input formats for SECRETS, ORGS, and REPOS variables:
SECRETS=SECRET1,SECRET2,SECRET3
ORGS=org1,org2,org3
REPOS=org1/repo1,org2/repo2,org3/repo3SECRETS="SECRET1
SECRET2
SECRET3"
ORGS="org1
org2
org3"
REPOS="org1/repo1
org2/repo2
org3/repo3"SECRETS="SECRET1,SECRET2
SECRET3"
ORGS="org1,org2
org3"Note: Extra whitespace and empty items are automatically handled and filtered out.
Create a .env file in your project directory:
# Gitea Configuration
GITEA_SERVER=https://gitea.example.com
GITEA_TOKEN=your_gitea_access_token
GITEA_SKIP_VERIFY=false
# Secrets to sync (comma-separated format)
SECRETS=DATABASE_URL,API_KEY,JWT_SECRET
# Alternative: newline-separated format
# SECRETS="DATABASE_URL
# API_KEY
# JWT_SECRET"
# Secret values
DATABASE_URL=postgresql://user:pass@localhost/db
API_KEY=sk-1234567890abcdef
JWT_SECRET=super-secret-jwt
# Target organizations and repositories (comma-separated)
ORGS=my-org,another-org
REPOS=my-org/repo1,my-org/repo2,another-org/repo3
# Alternative: newline-separated format
# ORGS="my-org
# another-org"
# REPOS="my-org/repo1
# my-org/repo2
# another-org/repo3"
# Optional: Enable dry-run mode
DRY_RUN=falseexport GITEA_SERVER=https://gitea.example.com
export GITEA_TOKEN=your_gitea_access_token
export SECRETS=DATABASE_URL,API_KEY,JWT_SECRET
export DATABASE_URL=postgresql://user:pass@localhost/db
export API_KEY=sk-1234567890abcdef
export JWT_SECRET=super-secret-jwt
export ORGS=my-org,another-org
export REPOS=my-org/repo1,my-org/repo2export INPUT_GITEA_SERVER=https://gitea.example.com
export INPUT_GITEA_TOKEN=your_gitea_access_token
export INPUT_SECRETS=DATABASE_URL,API_KEY,JWT_SECRET
export INPUT_DATABASE_URL=postgresql://user:pass@localhost/db
export INPUT_API_KEY=sk-1234567890abcdef
export INPUT_JWT_SECRET=super-secret-jwt
export INPUT_ORGS=my-org,another-org
export INPUT_REPOS=my-org/repo1,my-org/repo2# Load configuration from .env file and sync secrets
./gitea-secret-sync
# Use custom environment file
./gitea-secret-sync -env-file production.env# Preview what would be changed without actually updating
DRY_RUN=true ./gitea-secret-sync# Update secrets only for specific organizations
export GITEA_SERVER=https://gitea.example.com
export GITEA_TOKEN=your_token
export SECRETS=SECRET1,SECRET2
export SECRET1=value1
export SECRET2=value2
export ORGS=org1,org2
./gitea-secret-sync# Update secrets only for specific repositories
export GITEA_SERVER=https://gitea.example.com
export GITEA_TOKEN=your_token
export SECRETS=SECRET1,SECRET2
export SECRET1=value1
export SECRET2=value2
export REPOS=org1/repo1,org1/repo2,org2/repo3
./gitea-secret-sync# Example using newline-separated format for better readability
export GITEA_SERVER=https://gitea.example.com
export GITEA_TOKEN=your_token
export SECRETS="DATABASE_URL
API_KEY
JWT_SECRET
WEBHOOK_SECRET"
export DATABASE_URL=postgresql://user:pass@localhost/db
export API_KEY=sk-1234567890abcdef
export JWT_SECRET=super-secret-jwt
export WEBHOOK_SECRET=whsec_1234567890
export ORGS="production-org
staging-org
development-org"
./gitea-secret-sync- Log in to your Gitea instance
- Go to Settings → Applications → Generate New Token
- Select the required scopes:
write:organization(for organization secrets)write:repository(for repository secrets)
- Copy the generated token and use it as
GITEA_TOKEN
The tool includes comprehensive error handling:
- Invalid Configuration: Missing required variables will cause the program to exit with an error message
- Network Issues: Connection problems are logged with detailed error information
- API Errors: Gitea API errors are captured and logged with context
- Invalid Repository Format: Repository names must be in
org/repoformat - Graceful Shutdown: The tool handles SIGINT and SIGTERM signals gracefully
The tool uses structured logging with the following log levels:
INFO: Normal operation informationWARN: Warnings (e.g., dry-run mode notifications)ERROR: Error conditions that prevent operation
Log format includes timestamp, level, message, and relevant context fields.
git clone https://github.com/appleboy/gitea-secret-sync.git
cd gitea-secret-sync
go build -o gitea-secret-sync ./cmdgo test ./cmdcmd/
├── gitea.go # Gitea client wrapper with SSL configuration
├── main.go # Main application entry point and logic
├── util.go # Utility functions for environment variables and string parsing
├── util_test.go # Unit tests for utility functions
└── util_split_test.go # Unit tests for string splitting functionalitygitea.go: Implements the Gitea client wrapper with SSL configuration supportmain.go: Contains the main application logic, signal handling, and batch processingutil.go: Provides utility functions for reading environment variables with INPUT_ prefix support and flexible string parsing (comma/newline separation)util_test.go: Unit tests for utility functionsutil_split_test.go: Unit tests for the new string splitting functionality
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Token Security: Store your Gitea tokens securely and never commit them to version control
- SSL Verification: Only disable SSL verification (
GITEA_SKIP_VERIFY=true) for trusted internal networks - Dry Run: Always test with
DRY_RUN=truebefore making actual changes - Secret Values: Ensure secret values are properly escaped and don't contain special characters that might cause parsing issues
- Ensure
GITEA_SERVERandGITEA_TOKENenvironment variables are set
- Repository names must be in
org/repoformat (e.g.,myorg/myrepo)
- Check if your Gitea token has sufficient permissions
- Verify that the organization or repository exists
- Ensure the Gitea server is accessible
- Set
GITEA_SKIP_VERIFY=truefor self-signed certificates (not recommended for production) - Or properly configure SSL certificates
If you encounter issues:
- Enable dry-run mode to check configuration:
DRY_RUN=true - Check the logs for detailed error messages
- Verify your Gitea token permissions
- Test connectivity to your Gitea server
Made with ❤️ for the Gitea community