{"id":51620784,"url":"https://github.com/barisdemirhan/ghsecret","last_synced_at":"2026-07-12T19:01:20.126Z","repository":{"id":348284107,"uuid":"1196684568","full_name":"barisdemirhan/ghsecret","owner":"barisdemirhan","description":"Push .env variables to GitHub Secrets \u0026 Variables — with smart conflict detection and precedence warnings.","archived":false,"fork":false,"pushed_at":"2026-03-31T15:31:26.000Z","size":56,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-31T15:35:29.011Z","etag":null,"topics":["cli","developer-tools","dotenv","env","github","github-actions","ink","nodejs","react","secrets","typescript","variables"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/ghsecret","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/barisdemirhan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-31T00:05:58.000Z","updated_at":"2026-03-31T15:30:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/barisdemirhan/ghsecret","commit_stats":null,"previous_names":["barisdemirhan/ghsecret"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/barisdemirhan/ghsecret","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barisdemirhan%2Fghsecret","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barisdemirhan%2Fghsecret/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barisdemirhan%2Fghsecret/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barisdemirhan%2Fghsecret/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barisdemirhan","download_url":"https://codeload.github.com/barisdemirhan/ghsecret/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barisdemirhan%2Fghsecret/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35400291,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","developer-tools","dotenv","env","github","github-actions","ink","nodejs","react","secrets","typescript","variables"],"created_at":"2026-07-12T19:01:19.378Z","updated_at":"2026-07-12T19:01:20.116Z","avatar_url":"https://github.com/barisdemirhan.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Built with Claude Code](https://img.shields.io/badge/Built_with-Claude_Code-D97757?logo=claude\u0026logoColor=fff)\n\n**English** | [Türkçe](README.tr.md)\n\n# ghsecret\n\nPush `.env` variables to GitHub Secrets \u0026 Variables — with smart conflict detection and precedence warnings.\n\n```bash\n# Push all .env vars as secrets\nghsecret -s -a\n\n# Interactive mode — pick keys, choose target, decide per key\nghsecret -i\n```\n\n## Why\n\nManaging GitHub Secrets and Variables through the web UI is slow and error-prone. `ghsecret` reads your `.env` file and pushes values directly via the GitHub CLI — with safety checks that prevent common mistakes:\n\n- **Detects existing values** before overwriting and asks for confirmation\n- **Warns about GitHub's precedence rules** (Environment \u003e Repository \u003e Organization) so you don't push a secret that gets silently shadowed\n- **Detailed error messages** for permission issues, rate limits, and network errors\n- **Dry run mode** to preview what would happen without touching anything\n\n## Quick Start (no install)\n\n```bash\n# Interactive mode — guided step by step\nnpx ghsecret -i\n\n# Push a single key as secret\nnpx ghsecret -s -k DB_PASSWORD\n\n# From a specific file\nnpx ghsecret -s -a -f .env.production\n\n# Push all keys as variables (dry run first)\nnpx ghsecret -v -a --dry-run\n\n# Push to a specific environment\nnpx ghsecret -s -k API_KEY --env staging\n\n# Push to organization\nnpx ghsecret -v -k SLACK_WEBHOOK --org my-org\n\n# Push to a specific repo (skip remote selection)\nnpx ghsecret -s -a --repo my-org/my-repo\n```\n\n## Install\n\n```bash\n# Global install for repeated use\nnpm install -g ghsecret\n\n# Or clone and link\ngit clone https://github.com/barisdemirhan/ghsecret.git\ncd ghsecret \u0026\u0026 npm install \u0026\u0026 npm run build \u0026\u0026 npm link\n```\n\n**Requires:** [GitHub CLI (`gh`)](https://cli.github.com) authenticated via `gh auth login` and Node.js 18+.\n\n## Usage\n\n```\nghsecret -s|-v [options]              Push as secret or variable\nghsecret -i                           Interactive mode\nghsecret push \u003ckey1\u003e \u003ckey2\u003e ... -s    Push specific keys\n```\n\n### Modes\n\n| Flag | Description |\n|------|-------------|\n| `-s, --secret` | Push as GitHub Secret |\n| `-v, --variable` | Push as GitHub Variable |\n| `-i, --interactive` | Interactive picker (choose file, target, keys, and mode) |\n\n### Options\n\n| Flag | Description |\n|------|-------------|\n| `-f, --file \u003cpath\u003e` | Env file path (default: `.env`) |\n| `-a, --all` | Push all keys from the file |\n| `-k, --keys \u003ck1,k2\u003e` | Comma-separated keys to push |\n| `--org \u003cname\u003e` | Push to organization level |\n| `--env \u003cname\u003e` | Push to environment level |\n| `--dry-run` | Preview without pushing |\n| `--force` | Skip confirmation prompts |\n| `--repo \u003cowner/repo\u003e` | Target specific repository (skips remote selection) |\n\n## Examples\n\n```bash\n# Push all vars as secrets\nghsecret -s -a\n\n# Push specific keys as variables\nghsecret -v -k APP_NAME,APP_URL,APP_ENV\n\n# From a specific file with dry run\nghsecret -s -a -f .env.production --dry-run\n\n# Push to staging environment\nghsecret -s -k DB_HOST,DB_PASSWORD --env staging\n\n# Push to organization\nghsecret -v -k SLACK_WEBHOOK --org my-org\n\n# CI/CD — no prompts\nghsecret -s -a --force\n\n# Target a specific repo (useful with multiple remotes)\nghsecret -s -a --repo my-org/my-repo\n```\n\n## Interactive Mode\n\nRun `ghsecret -i` for a guided experience:\n\n```\n📁 Env file path:\n  › .env.production\n\n🎯 Push target:\n ❯ 📦 Repository\n   🏢 Organization\n   🌍 Environment\n\n📋 Variables in .env.production:\n─────────────────────────────────────────\n ❯ ◉  APP_NAME                      = ••••••••\n   ◉  APP_ENV                       = ••••••••\n   ○  DB_HOST                       = ••••••••\n   ◉  DB_PASSWORD                   = ••••••••\n   ○  REDIS_URL                     = ••••••••\n\n ↑↓ navigate · space select · a toggle all · enter confirm · q quit\n 3 selected\n\nPush as:\n ❯ 🔒 Secret\n   📋 Variable\n   🔀 Mixed (choose per key)\n```\n\n## Remote Selection\n\nWhen multiple git remotes are detected, ghsecret asks which repo to target:\n\n```\n🔗 Multiple remotes found. Push to which repo?\n ❯ origin   → barisdemirhan/ghsecret\n   upstream → someorg/ghsecret\n```\n\nTo skip the prompt, use `--repo`:\n\n```bash\nghsecret -s -a --repo someorg/ghsecret\n```\n\n## Push Progress\n\nEach key is pushed one at a time with real-time feedback:\n\n```\n ✓ APP_NAME → 🔒 secret\n ✓ DB_HOST → 📋 variable\n ✗ BAD_KEY — Permission denied\n⠋ Pushing 4/15... API_KEY → 🔒 secret\n```\n\n## Safety Features\n\n### Conflict Detection\n\nBefore pushing, ghsecret checks if keys already exist at the target level:\n\n```\n⚠ 2 key(s) already exist at this level:\n  • DB_PASSWORD (updated: 3/15/2026)\n  • API_KEY (updated: 3/1/2026)\n\n [a] Overwrite all · [s] Select · [n] Cancel\n```\n\nPress `s` to pick which keys to overwrite individually:\n\n```\n⚠ Which keys should be overwritten?\n ❯ ◉  DB_PASSWORD   (updated: 3/15/2026)\n   ○  API_KEY        (updated: 3/1/2026)\n\n ↑↓ navigate · space toggle · a all · enter confirm · q cancel\n 1 selected — selected will be overwritten, others skipped\n```\n\n### Precedence Warnings\n\nGitHub resolves secrets and variables with a priority system: **Environment \u003e Repository \u003e Organization**. ghsecret detects when your push would be ineffective:\n\n```\n🚫 1 key(s) are shadowed by a higher-priority level:\n  GitHub precedence: Environment \u003e Repository \u003e Organization\n  • DB_PASSWORD — Repository level has the same key and will take priority\n  These values will NOT be used at runtime!\nSome keys will be shadowed. Continue anyway? [y/N]\n```\n\nOr when your push overrides a lower-priority level:\n\n```\nℹ 1 key(s) will override lower-priority values:\n  • DB_PASSWORD — Will override the Organization-level value\n```\n\n### Environment Auto-Create\n\nWhen pushing to an environment that doesn't exist yet, ghsecret offers to create it:\n\n```\n⚠ Environment \"staging\" does not exist in this repository.\nCreate environment \"staging\" and continue? [y/N]\n```\n\n### Error Handling\n\nClear, actionable error messages instead of raw API errors:\n\n| Scenario | Message |\n|----------|---------|\n| Insufficient permissions | `Permission denied. Check your token scopes and repo access.` |\n| Repo/org not found | `Resource not found. Check the repo, org, or environment name.` |\n| Rate limited | `Rate limited by GitHub API. Wait a moment and try again.` |\n| Network issue | `Network error. Check your internet connection.` |\n\n### Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| `0` | Success |\n| `1` | Error or user cancelled |\n\nWorks correctly with `\u0026\u0026` chaining and CI pipelines.\n\n## .env Format\n\nSupports all common formats including multiline values:\n\n```env\n# Comments are skipped\nAPP_NAME=MyApp\nAPP_URL=\"https://example.com\"\nAPP_KEY='base64:abc123'\nexport DB_HOST=localhost\nINLINE=value # inline comments are stripped\n\n# Multiline values\nPRIVATE_KEY=\"-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA...\n-----END RSA PRIVATE KEY-----\"\n```\n\n## Uninstall\n\n```bash\nnpm uninstall -g ghsecret\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarisdemirhan%2Fghsecret","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarisdemirhan%2Fghsecret","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarisdemirhan%2Fghsecret/lists"}