Metadata-Version: 2.4
Name: pushforge
Version: 0.1.0
Summary: One-command GitHub DevSecOps CLI. Forge your code. Push anywhere.
Author-email: sifuna codex <www.antonysifuna07@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/aasz253/PushForge
Project-URL: Repository, https://github.com/aasz253/PushForge
Project-URL: Documentation, https://github.com/aasz253/PushForge#readme
Project-URL: Issues, https://github.com/aasz253/PushForge/issues
Project-URL: Source Code, https://github.com/aasz253/PushForge
Keywords: github,git,devsecops,cli,automation
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Version Control
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer<1.0,>=0.12
Requires-Dist: rich<15.0,>=13.7
Requires-Dist: requests<3.0,>=2.31
Requires-Dist: keyring<26.0,>=24.3
Requires-Dist: platformdirs<5.0,>=4.0
Requires-Dist: tomli-w<3.0,>=1.0
Provides-Extra: dev
Requires-Dist: pytest<9.0,>=8.0; extra == "dev"
Requires-Dist: pytest-cov<6.0,>=5.0; extra == "dev"
Requires-Dist: ruff<1.0,>=0.5; extra == "dev"
Requires-Dist: mypy<2.0,>=1.10; extra == "dev"
Requires-Dist: bandit<2.0,>=1.7; extra == "dev"
Requires-Dist: pip-audit<3.0,>=2.7; extra == "dev"
Requires-Dist: build<2.0,>=1.2; extra == "dev"
Requires-Dist: twine<6.0,>=5.0; extra == "dev"
Requires-Dist: pre-commit<4.0,>=3.8; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+">
  <img src="https://img.shields.io/github/license/aasz253/PushForge" alt="License: MIT">
</p>

# PushForge

> **PushForge turns publishing a local project to GitHub into one command.**

```bash
pipx install pushforge

cd my-project

pushforge
```

No `git init`. No GitHub repository setup. No remote configuration. No
copy/paste commands. No repeated authentication.

Just:

```bash
pushforge
```

A cross-platform **DevSecOps CLI** for one-command project publishing and
GitHub automation — not merely "a GitHub uploader."

Code → PushForge → *Detect* → *Secure* → *Git* → *GitHub* → *CI/CD* → *Deployment*

---

## Highlights

- **One install.** `pipx install pushforge`
- **One GitHub connection.** Keep logged in once; every project after that is one command.
- **One command per project.** `pushforge` works in a brand-new or existing project.
- **Security-first.** Automatic secret scanning blocks accidental credential leaks before they ever reach GitHub.
- **Smart detection.** Identifies your stack and generates a tailored `.gitignore`.
- **Safe by design.** Never force-pushes by default, never overwrites repositories, never stores credentials in project files.

## How it works

Running `pushforge` inside any project:

```
✓ GitHub account connected            (only the first time)
✓ Project detected                    Python / FastAPI
✓ .gitignore generated
✓ Security scan completed
✓ Git repository initialized
✓ GitHub repository created
✓ Initial commit created
✓ Remote origin configured
✓ Code pushed successfully

🚀 Project pushed successfully!

Repository:
https://github.com/you/my-project
```

Everything is incremental and safe:

| Local state                     | What PushForge does                                    |
| ------------------------------- | ------------------------------------------------------ |
| No `.git/`, no remote           | `init`, name, create repo, commit, push                |
| `.git/` exists, no remote       | Link the project to a new GitHub repository            |
| `.git/` + `origin` → GitHub     | Verify the repo, then push new commits — no duplicate  |
| Repo already matches            | Pushes anything new, reports "up to date"              |

## Installation

### Requirements

- Python **3.11+**
- `git` available on `PATH`

### Recommended — install from source (PyPI release coming soon)

PushForge is not published to PyPI yet. Install it from the GitHub repository
with `pipx` (auto-isolates and puts `pushforge` on your PATH):

```bash
git clone https://github.com/aasz253/PushForge
cd PushForge
pipx install .

# once installed, it works in ANY folder:
cd /any/project
pushforge
```

> `pipx ensurepath` (run it once) may be needed if `~/.local/bin` isn't already
> on your PATH.

### Or pip (user install)

```bash
git clone https://github.com/aasz253/PushForge
cd PushForge
pip install --user .
```

Verify the install works globally (from any directory):

```bash
pushforge --version
```

### Per-OS install notes

#### Linux / macOS — pipx (recommended)

```bash
sudo apt install pipx          # Debian/Ubuntu — or: brew install pipx
git clone https://github.com/aasz253/PushForge
cd PushForge
pipx install .
pipx ensurepath                # one-time, adds ~/.local/bin to PATH
```

No pipx? Use the venv + symlink pattern (works for any user; the entry point
lands on PATH in `~/.local/bin`):

```bash
git clone https://github.com/aasz253/PushForge
cd PushForge
python3 -m venv ~/.local/share/pushforge-venv
~/.local/share/pushforge-venv/bin/pip install .
ln -s ~/.local/share/pushforge-venv/bin/pushforge ~/.local/bin/pushforge
```

#### Windows — PowerShell

```bash
git clone https://github.com/aasz253/PushForge
cd PushForge
py -m venv "$env:LOCALAPPDATA\pushforge-venv"
& "$env:LOCALAPPDATA\pushforge-venv\Scripts\python.exe" -m pip install .
New-Item -Type Directory -Force "$env:LOCALAPPDATA\Programs" | Out-Null
Copy-Item "$env:LOCALAPPDATA\pushforge-venv\Scripts\pushforge.exe" "$env:LOCALAPPDATA\Programs\pushforge.exe"
# Add "$env:LOCALAPPDATA\Programs" to your PATH if missing:
#   start ms-settings:appsfeatures (Settings → "Edit environment variables")
```

Once installed on any OS, PushForge works from **any folder**:

```bash
cd /any/folder
pushforge            # works everywhere
```

## Quick start

### 1. Connect GitHub (once)

```bash
pushforge auth login
```

You will never be asked for your GitHub password. PushForge uses:

- the **GitHub CLI** device-flow login when `gh` is installed, or
- the **GitHub OAuth device flow** (set `PUSHFORGE_CLIENT_ID` to your GitHub
  App client ID to use it directly), or
- an existing `GH_TOKEN` / `GITHUB_TOKEN` environment variable.

Credentials are stored in your operating system's secure keyring (or a
user-only permission file), never inside a project.

Check the state at any time:

```bash
pushforge auth status
```

### 2. Publish a project

```bash
cd ~/projects/ai-knowledge-assistant
pushforge
```

That's it. A commit is created on `main` and pushed to a new (or existing)
GitHub repository matching the project name.

## Authentication

| Command                  | Description                                   |
| ------------------------ | --------------------------------------------- |
| `pushforge auth login`   | Connect your GitHub account (device flow / gh) |
| `pushforge auth status`  | Show account + credential source              |
| `pushforge auth logout`  | Remove stored credentials                     |

If you run `pushforge` without authentication, the setup flow launches
automatically and the original operation **resumes** once you're connected.

Tokens are never printed, never written to `.env`, never committed, and never
appear in error messages.

## Commands

```bash
pushforge                     # One-command publish
pushforge auth login|status|logout
pushforge scan                # Scan project for secrets
pushforge status              # Project / repo / auth summary
pushforge config              # View or update configuration
pushforge version             # Show version
```

### Options for `pushforge`

```bash
pushforge --private            # private repository
pushforge --public             # public repository (default)
pushforge --name my-repo       # override repository name
pushforge -m "feat: init"      # custom commit message
pushforge --description "..."  # repository description
pushforge --force              # push with --force-with-lease (explicit opt-in)
pushforge --force-remote       # replace an existing origin remote
pushforge --skip-security      # disable the secret scan (not recommended)
pushforge --level strict       # stricter secret scanning
pushforge --dry-run            # preview without changing anything
```

## Security model

Before any push, PushForge scans your project and looks for:

- API keys (AWS, Google, Stripe, GitHub, Slack…)
- private key material (`-----BEGIN … PRIVATE KEY-----`, `*.pem`, `*.key`)
- database connection strings with embedded credentials
- `.env` and credential files
- high-entropy token assignments in source files

If a likely secret is found, the push is **blocked**:

```
⚠ Potential secret detected

File:   config.py:12
Finding: AWS access key

Push blocked to protect your credentials.
Remove the secret and try again.
```

Secret values are never displayed — at most a non-reversible fingerprint is.

PushForge also **never**:

- force-pushes unless you pass `--force` (and then it uses `--force-with-lease`)
- overwrites an existing GitHub repository
- overwrites an existing `.gitignore` (it only appends missing rules)
- swaps an existing remote without `--force-remote`
- auto-deletes data

## Repository naming & visibility

- Names are suggested from the directory name and normalized (e.g.
  `~/Projects/AI Assistant` → `ai-assistant`).
- Default visibility is **public**; override per-project with `--private` /
  `--public`, or persist a preference:

```bash
pushforge config --visibility private
```

## Configuration

```bash
pushforge config                                     # show current config
pushforge config --visibility private
pushforge config --branch trunk
pushforge config --commit-message "chore: sync"
pushforge config --security-level strict
pushforge config --username octocat
```

Environment overrides (`PUSHFORGE_VISIBILITY`, `PUSHFORGE_BRANCH`,
`PUSHFORGE_CLIENT_ID`) take precedence over stored values. Configuration lives
in your user config directory, never in a project.

## Supported platforms

- **Linux** (Debian/Ubuntu, Fedora, Arch and derivatives)
- **macOS** (Intel and Apple Silicon)
- **Windows** (PowerShell and Command Prompt)

Paths are handled with Python's platform-independent APIs.

## Stack detection

PushForge recognizes common markers out of the box:

| Marker                     | Detected                  |
| -------------------------- | ------------------------- |
| `requirements.txt` / `pyproject.toml` | Python          |
| `package.json`             | Node.js / JavaScript      |
| `tsconfig.json`            | TypeScript                |
| `next.config.*`            | Next.js                   |
| `pom.xml` / `build.gradle` | Java Maven / Gradle       |
| `go.mod`                   | Go                        |
| `Cargo.toml`               | Rust                      |
| `Dockerfile`               | Docker                    |
| `docker-compose.yml`       | Docker Compose            |
| `*.tf`                     | Terraform                 |
| `Chart.yaml` / `*.k8s.yaml`| Kubernetes / Helm         |

Detection powers tailored `.gitignore` generation and the foundation for
future DevSecOps automation (pipeline, dockerize, deploy, secure).

## Architecture

```
src/pushforge/
├── cli.py            # Typer CLI surface
├── workflow.py       # ordered publish pipeline
├── github/           # auth, API client, repository ops
├── git/              # manager, remotes, commits
├── detection/        # stack detection + .gitignore
├── security/         # secret patterns + scanner
├── config/           # user configuration
├── templates/        # .gitignore templates
└── ui/               # Rich terminal rendering
```

GitHub API logic is separate from Git operations; authentication is separate
from repository creation; the security scanner is CLI-independent. Components
are injected so they can be tested independently.

## Roadmap

- `pushforge pipeline` — generate GitHub Actions workflows for your stack
- `pushforge dockerize` — add Dockerfile/docker-compose generation
- `pushforge deploy` — deploy targets for common platforms
- `pushforge secure` — deep dependency & configuration auditing
- `pushforge ai` — LLM-assisted READMEs, commit messages, security explains
- Native installers and package managers

The MVP works entirely without AI; these features are designed to be added
without rewriting the core.

## Development

```bash
git clone https://github.com/aasz253/PushForge
cd PushForge

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

pytest
ruff check .
ruff format --check .
mypy src/pushforge
bandit -r src/ -c pyproject.toml
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). All contributions must pass lint,
type-checking, the test suite, and a security scan.

## Security policy

See [SECURITY.md](SECURITY.md) for reporting vulnerabilities. Never open a
public issue with credentials or tokens.

## License

[MIT](LICENSE)

---

**Forge your code. Push anywhere.** ⚒
<span align="center">
    Created by **Sifuna Codex**
</span>
