Skip to content

Commit 92d13e6

Browse files
committed
feat: add Docker, standalone binaries, and Homebrew distribution
- Add multi-stage Dockerfile + .dockerignore - Add GitHub Actions workflow for Docker image on ghcr.io - Add PyInstaller workflow for macOS/Linux/Windows binaries on release - Add Homebrew formula - Update README with all installation methods (PyPI, pipx, binaries, Homebrew, Docker) - Add PyPI and Docker badges
1 parent fe6db64 commit 92d13e6

6 files changed

Lines changed: 237 additions & 2 deletions

File tree

.dockerignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.git
2+
.github
3+
.pytest_cache
4+
.ruff_cache
5+
.venv
6+
__pycache__
7+
*.egg-info
8+
dist
9+
build
10+
.env

.github/workflows/binaries.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Build Standalone Binaries
2+
3+
on:
4+
push:
5+
tags: ["v*"]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
build:
12+
strategy:
13+
matrix:
14+
include:
15+
- os: ubuntu-latest
16+
artifact: ossguard-linux-amd64
17+
pyinstaller_args: ""
18+
- os: macos-latest
19+
artifact: ossguard-macos-arm64
20+
pyinstaller_args: ""
21+
- os: windows-latest
22+
artifact: ossguard-windows-amd64.exe
23+
pyinstaller_args: ""
24+
25+
runs-on: ${{ matrix.os }}
26+
27+
steps:
28+
- uses: actions/checkout@v6
29+
30+
- uses: actions/setup-python@v6
31+
with:
32+
python-version: "3.12"
33+
34+
- name: Install dependencies
35+
run: |
36+
pip install -e .
37+
pip install pyinstaller
38+
39+
- name: Build binary
40+
run: |
41+
pyinstaller --onefile --name ossguard --clean \
42+
--hidden-import ossguard.analyzers \
43+
--hidden-import ossguard.generators \
44+
--hidden-import ossguard.parsers \
45+
--hidden-import ossguard.apis \
46+
--collect-submodules ossguard \
47+
src/ossguard/cli.py
48+
shell: bash
49+
50+
- name: Rename artifact
51+
run: |
52+
if [ "${{ runner.os }}" = "Windows" ]; then
53+
mv dist/ossguard.exe "dist/${{ matrix.artifact }}"
54+
else
55+
mv dist/ossguard "dist/${{ matrix.artifact }}"
56+
fi
57+
shell: bash
58+
59+
- name: Upload artifact
60+
uses: actions/upload-artifact@v7
61+
with:
62+
name: ${{ matrix.artifact }}
63+
path: dist/${{ matrix.artifact }}
64+
65+
release:
66+
needs: build
67+
runs-on: ubuntu-latest
68+
permissions:
69+
contents: write
70+
steps:
71+
- name: Download all artifacts
72+
uses: actions/download-artifact@v8
73+
74+
- name: Generate checksums
75+
run: |
76+
mkdir -p release
77+
for dir in ossguard-*; do
78+
cp "$dir"/* release/ 2>/dev/null || true
79+
done
80+
cd release
81+
sha256sum * > checksums-sha256.txt
82+
83+
- name: Upload to GitHub Release
84+
uses: softprops/action-gh-release@v2
85+
with:
86+
files: release/*
87+
fail_on_unmatched_files: false

.github/workflows/docker.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ["v*"]
7+
pull_request:
8+
branches: [main]
9+
10+
permissions:
11+
contents: read
12+
packages: write
13+
14+
jobs:
15+
build-and-push:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v6
19+
20+
- name: Set up Docker Buildx
21+
uses: docker/setup-buildx-action@v3
22+
23+
- name: Log in to GitHub Container Registry
24+
if: github.event_name != 'pull_request'
25+
uses: docker/login-action@v3
26+
with:
27+
registry: ghcr.io
28+
username: ${{ github.actor }}
29+
password: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Extract metadata
32+
id: meta
33+
uses: docker/metadata-action@v5
34+
with:
35+
images: ghcr.io/${{ github.repository }}
36+
tags: |
37+
type=ref,event=branch
38+
type=semver,pattern={{version}}
39+
type=semver,pattern={{major}}.{{minor}}
40+
type=sha
41+
42+
- name: Build and push
43+
uses: docker/build-push-action@v6
44+
with:
45+
context: .
46+
push: ${{ github.event_name != 'pull_request' }}
47+
tags: ${{ steps.meta.outputs.tags }}
48+
labels: ${{ steps.meta.outputs.labels }}
49+
cache-from: type=gha
50+
cache-to: type=gha,mode=max

Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FROM python:3.12-slim AS builder
2+
3+
WORKDIR /app
4+
COPY pyproject.toml README.md LICENSE ./
5+
COPY src/ src/
6+
7+
RUN pip install --no-cache-dir build && \
8+
python -m build --wheel && \
9+
pip install --no-cache-dir dist/*.whl
10+
11+
FROM python:3.12-slim
12+
13+
LABEL org.opencontainers.image.source="https://github.com/kirankotari/ossguard"
14+
LABEL org.opencontainers.image.description="One CLI to guard any OSS project with OpenSSF security best practices"
15+
LABEL org.opencontainers.image.licenses="Apache-2.0"
16+
17+
RUN apt-get update && \
18+
apt-get install -y --no-install-recommends git && \
19+
rm -rf /var/lib/apt/lists/*
20+
21+
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
22+
COPY --from=builder /usr/local/bin/ossguard /usr/local/bin/ossguard
23+
24+
RUN useradd --create-home ossguard
25+
USER ossguard
26+
WORKDIR /project
27+
28+
ENTRYPOINT ["ossguard"]
29+
CMD ["--help"]

Formula/ossguard.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Ossguard < Formula
2+
desc "One CLI to guard any OSS project with OpenSSF security best practices"
3+
homepage "https://github.com/kirankotari/ossguard"
4+
url "https://github.com/kirankotari/ossguard/archive/refs/tags/v0.1.0.tar.gz"
5+
license "Apache-2.0"
6+
7+
depends_on "python@3.12"
8+
9+
def install
10+
virtualenv_install_with_resources
11+
end
12+
13+
test do
14+
assert_match "ossguard", shell_output("#{bin}/ossguard version")
15+
end
16+
end

README.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
**One CLI to guard any OSS project with OpenSSF security best practices — bootstrap, scan, and monitor.**
44

55
[![CI](https://github.com/kirankotari/ossguard/actions/workflows/ci.yml/badge.svg)](https://github.com/kirankotari/ossguard/actions/workflows/ci.yml)
6+
[![PyPI](https://img.shields.io/pypi/v/ossguard)](https://pypi.org/project/ossguard/)
7+
[![Docker](https://ghcr-badge.egpl.dev/kirankotari/ossguard/latest_tag?trim=major&label=docker)](https://github.com/kirankotari/ossguard/pkgs/container/ossguard)
68
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
79
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
810

@@ -22,12 +24,53 @@ But setting them all up manually takes **hours**. And once set up, there's no un
2224
2. **Analyze** — audit security posture, dependencies, vulnerabilities, and compliance
2325
3. **Remediate** — auto-fix issues, generate reports, and enforce policies
2426

25-
## Quick Start
27+
## Installation
28+
29+
### PyPI (recommended)
2630

2731
```bash
28-
# Install
2932
pip install ossguard
3033

34+
# Or with pipx (isolated install)
35+
pipx install ossguard
36+
```
37+
38+
### Standalone Binaries (no Python required)
39+
40+
Download pre-built binaries from [GitHub Releases](https://github.com/kirankotari/ossguard/releases):
41+
42+
```bash
43+
# macOS (Apple Silicon)
44+
curl -L https://github.com/kirankotari/ossguard/releases/latest/download/ossguard-macos-arm64 -o ossguard
45+
chmod +x ossguard && sudo mv ossguard /usr/local/bin/
46+
47+
# Linux (x86_64)
48+
curl -L https://github.com/kirankotari/ossguard/releases/latest/download/ossguard-linux-amd64 -o ossguard
49+
chmod +x ossguard && sudo mv ossguard /usr/local/bin/
50+
```
51+
52+
### Homebrew
53+
54+
```bash
55+
brew install kirankotari/tap/ossguard
56+
```
57+
58+
### Docker
59+
60+
```bash
61+
# Scan current directory
62+
docker run --rm -v "$(pwd):/project" ghcr.io/kirankotari/ossguard scan
63+
64+
# Bootstrap OpenSSF configs
65+
docker run --rm -v "$(pwd):/project" ghcr.io/kirankotari/ossguard init
66+
67+
# Any command works
68+
docker run --rm -v "$(pwd):/project" ghcr.io/kirankotari/ossguard audit
69+
```
70+
71+
## Quick Start
72+
73+
```bash
3174
# Bootstrap your project with all OpenSSF best practices
3275
cd your-project
3376
ossguard init

0 commit comments

Comments
 (0)