Skip to content

Commit edcbb8a

Browse files
committed
feat: Make repository PyPI compatible with automated publishing
- Restructured project to proper Python package layout - Moved main script to gtfo/cli.py and data files to gtfo/data/ - Created modern packaging configuration (pyproject.toml, updated setup.py) - Added MANIFEST.in to include data files in distribution - Completely rewrote README.md with professional documentation - Added GitHub Actions workflows for CI and automated PyPI publishing - Created PYPI_SETUP.md with detailed setup instructions - Updated .gitignore to exclude Python build artifacts - Package is now installable via 'pip install gtfobins' - Command 'gtfo' is available after installation - Supports Python 3.6+ and works cross-platform
1 parent 073ba53 commit edcbb8a

File tree

266 files changed

+622
-46
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

266 files changed

+622
-46
lines changed

.github/workflows/ci.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: '3.10'
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install flake8 black isort
25+
26+
- name: Lint with flake8
27+
run: |
28+
# stop the build if there are Python syntax errors or undefined names
29+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=.git,__pycache__,venv,build,dist
30+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
31+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=.git,__pycache__,venv,build,dist
32+
continue-on-error: true
33+
34+
- name: Check formatting with black
35+
run: |
36+
black --check gtfo/ || true
37+
continue-on-error: true
38+
39+
- name: Check import order with isort
40+
run: |
41+
isort --check-only gtfo/ || true
42+
continue-on-error: true
43+
44+
test:
45+
runs-on: ${{ matrix.os }}
46+
strategy:
47+
fail-fast: false
48+
matrix:
49+
os: [ubuntu-latest, macos-latest, windows-latest]
50+
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
51+
52+
steps:
53+
- uses: actions/checkout@v3
54+
55+
- name: Set up Python ${{ matrix.python-version }}
56+
uses: actions/setup-python@v4
57+
with:
58+
python-version: ${{ matrix.python-version }}
59+
60+
- name: Install dependencies
61+
run: |
62+
python -m pip install --upgrade pip
63+
pip install -e .
64+
65+
- name: Verify installation
66+
run: |
67+
gtfo --version
68+
69+
- name: Test basic functionality
70+
run: |
71+
# Test help command
72+
gtfo --help
73+
# Test a known binary (should work)
74+
gtfo cat || true
75+
# Test an unknown binary (should fail gracefully)
76+
gtfo nonexistentbinary || true
77+
shell: bash

.github/workflows/publish.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Build and Publish to PyPI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
tags:
7+
- 'v*'
8+
pull_request:
9+
branches: [ main, master ]
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
matrix:
16+
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
17+
18+
steps:
19+
- uses: actions/checkout@v3
20+
21+
- name: Set up Python ${{ matrix.python-version }}
22+
uses: actions/setup-python@v4
23+
with:
24+
python-version: ${{ matrix.python-version }}
25+
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install build wheel
30+
pip install -e .
31+
32+
- name: Test installation
33+
run: |
34+
gtfo --version
35+
gtfo bash || true # Allow failure for demo
36+
37+
build-and-publish:
38+
needs: test
39+
runs-on: ubuntu-latest
40+
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))
41+
42+
steps:
43+
- uses: actions/checkout@v3
44+
45+
- name: Set up Python
46+
uses: actions/setup-python@v4
47+
with:
48+
python-version: '3.10'
49+
50+
- name: Install build dependencies
51+
run: |
52+
python -m pip install --upgrade pip
53+
pip install build wheel twine
54+
55+
- name: Build package
56+
run: python -m build
57+
58+
- name: Check package
59+
run: twine check dist/*
60+
61+
- name: Publish to Test PyPI
62+
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
63+
env:
64+
TWINE_USERNAME: __token__
65+
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
66+
run: |
67+
twine upload --repository testpypi dist/* --skip-existing || true
68+
continue-on-error: true
69+
70+
- name: Publish to PyPI
71+
if: startsWith(github.ref, 'refs/tags/')
72+
env:
73+
TWINE_USERNAME: __token__
74+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
75+
run: |
76+
twine upload dist/*

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,29 @@ env.bak/
5757
venv.bak/
5858

5959
.idea/
60+
61+
# Python cache
62+
__pycache__/
63+
*.pyc
64+
*.pyo
65+
*.pyd
66+
.Python
67+
68+
# Build artifacts
69+
build/
70+
dist/
71+
*.egg-info/
72+
*.egg
73+
MANIFEST
74+
75+
# Testing
76+
.tox/
77+
.nox/
78+
.coverage
79+
.coverage.*
80+
.cache
81+
.pytest_cache/
82+
nosetests.xml
83+
coverage.xml
84+
*.cover
85+
.hypothesis/

MANIFEST.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include README.md
2+
include LICENSE
3+
recursive-include gtfo/data *.json

PYPI_SETUP.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# PyPI Publishing Setup Guide
2+
3+
This guide will help you set up automatic publishing to PyPI using GitHub Actions.
4+
5+
## Prerequisites
6+
7+
1. PyPI account: https://pypi.org/account/register/
8+
2. Test PyPI account (optional): https://test.pypi.org/account/register/
9+
10+
## Step 1: Generate API Tokens
11+
12+
### For PyPI (Production)
13+
14+
1. Log in to https://pypi.org
15+
2. Go to Account Settings → API tokens
16+
3. Click "Add API token"
17+
4. Token name: `github-actions-gtfobins`
18+
5. Scope: Select "Entire account" (for first upload) or specific project after first upload
19+
6. Copy the token (starts with `pypi-`)
20+
21+
### For Test PyPI (Optional)
22+
23+
1. Log in to https://test.pypi.org
24+
2. Follow the same steps as above
25+
3. Token name: `github-actions-gtfobins-test`
26+
27+
## Step 2: Add Secrets to GitHub Repository
28+
29+
1. Go to your repository on GitHub
30+
2. Navigate to Settings → Secrets and variables → Actions
31+
3. Click "New repository secret"
32+
33+
Add these secrets:
34+
- Name: `PYPI_API_TOKEN`
35+
Value: Your PyPI token (from Step 1)
36+
37+
- Name: `TEST_PYPI_API_TOKEN` (optional)
38+
Value: Your Test PyPI token
39+
40+
## Step 3: Test the Setup
41+
42+
### Test with Test PyPI (Recommended)
43+
44+
1. Make a commit to main/master branch
45+
2. Check Actions tab for build status
46+
3. If successful, package will be available at:
47+
```
48+
https://test.pypi.org/project/gtfobins/
49+
```
50+
51+
### Install from Test PyPI
52+
53+
```bash
54+
pip install -i https://test.pypi.org/simple/ gtfobins
55+
```
56+
57+
## Step 4: Production Release
58+
59+
To publish to production PyPI:
60+
61+
1. Create a new tag:
62+
```bash
63+
git tag v1.0.0
64+
git push origin v1.0.0
65+
```
66+
67+
2. The GitHub Action will automatically:
68+
- Run tests
69+
- Build the package
70+
- Publish to PyPI
71+
72+
3. Install from PyPI:
73+
```bash
74+
pip install gtfobins
75+
```
76+
77+
## Versioning
78+
79+
Remember to update the version in these files before creating a new release:
80+
- `gtfo/__init__.py`
81+
- `setup.py`
82+
- `setup.cfg`
83+
- `pyproject.toml`
84+
85+
## Manual Publishing (Alternative)
86+
87+
If you prefer manual publishing:
88+
89+
```bash
90+
# Install build tools
91+
pip install build twine
92+
93+
# Build the package
94+
python -m build
95+
96+
# Check the package
97+
twine check dist/*
98+
99+
# Upload to Test PyPI
100+
twine upload --repository testpypi dist/*
101+
102+
# Upload to PyPI
103+
twine upload dist/*
104+
```
105+
106+
## Troubleshooting
107+
108+
### Common Issues
109+
110+
1. **Token scope error**: For first upload, use "Entire account" scope
111+
2. **Package name conflict**: The name might be taken, consider `gtfobins-cli`
112+
3. **Version conflict**: Ensure version number is incremented
113+
114+
### Verification
115+
116+
After publishing, verify your package:
117+
118+
```bash
119+
# Create a new virtual environment
120+
python -m venv test_env
121+
source test_env/bin/activate # On Windows: test_env\Scripts\activate
122+
123+
# Install your package
124+
pip install gtfobins
125+
126+
# Test it
127+
gtfo --version
128+
gtfo bash
129+
```
130+
131+
## Security Notes
132+
133+
- Never commit tokens to the repository
134+
- Rotate tokens periodically
135+
- Use Test PyPI for testing before production releases
136+
- Consider using trusted publishing with OIDC (newer GitHub feature)

0 commit comments

Comments
 (0)