Skip to content
This repository was archived by the owner on Sep 30, 2025. It is now read-only.

Commit dd9cd38

Browse files
evilsocketmonoxgasbriangreunke
authored
new: added publish-to-pypi workflow (ENG-186) (#11)
* new: added publish-to-pypi workflow (ENG-186) * Refactor workflows. Update README. Add LICENSE. * Small README update * bugfix: fix CI job project name - updated project name in CI job poetry check - added pre-commit to check yaml and Github Actions * bugfix: poetry lock update * Updating workflow and preparing secrets+access * Add concurrency checks to workflow * Simplify workflow to only run on PRs and v-tag pushes * Separate CI and publish into separate workflows * Focus workflows down to just the main branch --------- Co-authored-by: monoxgas <[email protected]> Co-authored-by: Brian Greunke <[email protected]> Co-authored-by: Brian Greunke <[email protected]>
1 parent 2850952 commit dd9cd38

File tree

8 files changed

+506
-183
lines changed

8 files changed

+506
-183
lines changed

.github/workflows/ci.yml

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,69 @@
1-
name: Lint, Typecheck, and Test
1+
name: CI
22

33
on:
4-
push:
5-
branches: [ main, dev ]
64
pull_request:
7-
branches: [ main, dev ]
5+
branches: [main]
6+
push:
7+
branches: [main]
88

99
jobs:
10-
ci:
10+
validate:
11+
name: Validate
1112
strategy:
12-
fail-fast: false
13-
matrix:
14-
python-version: ["3.9", "3.10", "3.11"]
15-
13+
fail-fast: false
14+
matrix:
15+
python-version: ["3.9", "3.10", "3.11"]
1616
runs-on: ubuntu-latest
17-
1817
steps:
19-
- uses: actions/checkout@v2
18+
- name: Checkout code
19+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
20+
21+
- name: Setup Python ${{ matrix.python-version }}
22+
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
23+
with:
24+
python-version: ${{ matrix.python-version }}
2025

21-
- name: Set up Python
22-
uses: actions/setup-python@v2
23-
with:
24-
python-version: ${{ matrix.python-version }}
26+
- name: Install Poetry
27+
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd
2528

26-
- name: Setup Poetry
27-
uses: abatilo/actions-poetry@v2
29+
- name: Configure Poetry
30+
run: |
31+
poetry config virtualenvs.create true --local
32+
poetry config virtualenvs.in-project true --local
2833
29-
- name: Configure local .venv
30-
run: |
31-
poetry config virtualenvs.create true --local
32-
poetry config virtualenvs.in-project true --local
34+
- name: Cache dependencies
35+
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a
36+
with:
37+
path: ./.venv
38+
key: venv-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}
39+
restore-keys: |
40+
venv-${{ runner.os }}-py${{ matrix.python-version }}-
3341
34-
- uses: actions/cache@v3
35-
name: Cache Dependencies
36-
with:
37-
path: ./.venv
38-
key: venv-${{ hashFiles('poetry.lock') }}
42+
- name: Install package
43+
run: |
44+
poetry install --all-extras
3945
40-
- name: Install dependencies
41-
run: poetry install --all-extras
46+
- name: Validate version
47+
run: |
48+
POETRY_VERSION=$(poetry version -s)
49+
INIT_VERSION=$(python -c "import dreadnode_cli; print(dreadnode_cli.__version__)")
50+
if [ "$POETRY_VERSION" != "$INIT_VERSION" ]; then
51+
echo "Version mismatch: pyproject.toml ($POETRY_VERSION) != __init__.py ($INIT_VERSION)"
52+
exit 1
53+
fi
4254
43-
- name: Verify version match
44-
run: |
45-
toml_version=$(grep -oP '(?<=version = ")[^"]+' pyproject.toml | head -1)
46-
package_version=$(grep -oP '(?<=__version__ = ")[^"]+' dreadnode_cli/__init__.py)
47-
48-
if [ "$toml_version" != "$package_version" ]; then
49-
echo "Version mismatch detected!"
50-
echo "Version in pyproject.toml: $toml_version"
51-
echo "Version in package: $package_version"
52-
exit 1
53-
else
54-
echo "Versions match: $toml_version"
55-
fi
55+
- name: Lint
56+
run: poetry run ruff check --output-format=github dreadnode_cli
5657

57-
- name: Linting
58-
run: poetry run ruff dreadnode_cli/
58+
- name: Type check
59+
run: poetry run mypy --no-error-summary dreadnode_cli
5960

60-
- name: Typecheck
61-
run: poetry run mypy dreadnode_cli/
61+
- name: Test
62+
run: poetry run pytest --junitxml=pytest.xml dreadnode_cli
6263

63-
- name: Tests
64-
run: poetry run pytest dreadnode_cli/
64+
- name: Upload test results
65+
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882
66+
if: always()
67+
with:
68+
name: test-results-${{ matrix.python-version }}
69+
path: pytest.xml

.github/workflows/docker-build.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.

.github/workflows/publish.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Publish
2+
3+
on:
4+
push:
5+
tags: ["v*"]
6+
7+
jobs:
8+
publish-package:
9+
name: Publish Package
10+
environment: protected
11+
permissions:
12+
contents: read
13+
id-token: write
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
18+
19+
- name: Setup Python
20+
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
21+
with:
22+
python-version: "3.11"
23+
24+
- name: Install Poetry
25+
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd
26+
27+
- name: Configure Poetry
28+
run: |
29+
poetry config virtualenvs.create true --local
30+
poetry config virtualenvs.in-project true --local
31+
32+
- name: Install package
33+
run: poetry install --no-dev
34+
35+
- name: Validate version
36+
run: |
37+
TAG_VERSION=${GITHUB_REF#refs/tags/v}
38+
POETRY_VERSION=$(poetry version -s)
39+
INIT_VERSION=$(python -c "import dreadnode_cli; print(dreadnode_cli.__version__)")
40+
41+
if ! [[ $TAG_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
42+
echo "Invalid tag format: $TAG_VERSION. Must be vX.X.X"
43+
exit 1
44+
fi
45+
46+
if [ "$POETRY_VERSION" != "$INIT_VERSION" ]; then
47+
echo "Version mismatch: pyproject.toml ($POETRY_VERSION) != __init__.py ($INIT_VERSION)"
48+
exit 1
49+
fi
50+
51+
if [ "$TAG_VERSION" != "$POETRY_VERSION" ]; then
52+
echo "Tag ($TAG_VERSION) doesn't match pyproject.toml ($POETRY_VERSION)"
53+
exit 1
54+
fi
55+
56+
- name: Build and publish
57+
run: |
58+
poetry build
59+
poetry publish
60+
61+
publish-docker:
62+
name: Publish Docker
63+
environment: protected
64+
runs-on: ubuntu-latest
65+
steps:
66+
- name: Checkout code
67+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
68+
69+
- name: Setup QEMU
70+
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf
71+
72+
- name: Setup Docker Buildx
73+
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349
74+
75+
- name: Login to Docker Hub
76+
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
77+
with:
78+
username: ${{ secrets.DOCKERHUB_USERNAME }}
79+
password: ${{ secrets.DOCKERHUB_TOKEN }}
80+
81+
- name: Set Docker tags
82+
id: tags
83+
run: |
84+
VERSION=${GITHUB_REF#refs/tags/v}
85+
echo "tags=dreadnode/cli:latest,dreadnode/cli:$VERSION" >> $GITHUB_OUTPUT
86+
87+
- name: Build and push
88+
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355
89+
with:
90+
context: .
91+
platforms: linux/amd64,linux/arm64
92+
push: true
93+
tags: ${{ steps.tags.outputs.tags }}
94+
cache-from: type=gha
95+
cache-to: type=gha,mode=max

.pre-commit-config.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
repos:
2+
# Standard pre-commit hooks
3+
- repo: https://github.com/pre-commit/pre-commit-hooks
4+
rev: v4.6.0
5+
hooks:
6+
- id: check-yaml
7+
- id: trailing-whitespace
8+
9+
# Github actions
10+
- repo: https://github.com/rhysd/actionlint
11+
rev: v1.7.1
12+
hooks:
13+
- id: actionlint
14+
name: Check Github Actions

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 dreadnode
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,34 @@
1-
Dreadnode command line interface.
1+
<p align="center">
2+
<img
3+
src="https://d1lppblt9t2x15.cloudfront.net/logos/5714928f3cdc09503751580cffbe8d02.png"
4+
alt="Logo"
5+
align="center"
6+
width="144px"
7+
height="144px"
8+
/>
9+
</p>
10+
11+
<h3 align="center">
12+
Dreadnode command line interface
13+
</h3>
14+
15+
<h4 align="center">
16+
<img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/dreadnode-cli">
17+
<img alt="PyPI - Version" src="https://img.shields.io/pypi/v/dreadnode-cli">
18+
<img alt="GitHub License" src="https://img.shields.io/github/license/dreadnode/cli">
19+
<img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/dreadnode/cli/ci.yml">
20+
</h4>
21+
22+
</br>
223

324
## Installation
425

26+
### From PyPi:
27+
28+
```bash
29+
pip install dreadnode-cli
30+
```
31+
532
### With Poetry:
633

734
This project is packaged for and meant to be used with the [Poetry package management tool](https://python-poetry.org/).

0 commit comments

Comments
 (0)