Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
!resources
!alembic.ini
!pyproject.toml
!poetry.lock
!uv.lock
!startup.sh
!.env
32 changes: 27 additions & 5 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,32 @@ on:
push:
paths:
- Dockerfile.base
- poetry.lock
- uv.lock
workflow_dispatch:

jobs:
sync-requirements:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0

- name: Export requirements.txt for Dependabot
run: |
uv export --frozen --no-hashes -o requirements.txt
if ! git diff --quiet requirements.txt; then
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add requirements.txt
git commit -m "Update requirements.txt from uv.lock"
git push
fi

build:
runs-on: ubuntu-latest
permissions:
Expand All @@ -17,20 +39,20 @@ jobs:
DOCKER_IMAGE: ghcr.io/hackthebox/hackster:base
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

- name: Login to ghcr.io
uses: docker/login-action@v3
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build image
uses: docker/build-push-action@v5
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
with:
push: true
context: .
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ jobs:
DEPLOYMENT_NAME: ${{ (contains(github.ref, '-rc')) && 'hackster-dev' || 'hackster' }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Login to ghcr.io
uses: docker/login-action@v3
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image
uses: docker/build-push-action@v5
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
with:
push: true
context: .
tags: ${{ env.DOCKER_IMAGE }},${{ env.LATEST_IMAGE }}
- name: Rollout release
uses: makelarisjr/kubectl-action@v1
uses: makelarisjr/kubectl-action@6a140d582feb88b20e91ee8e35d15c255865ab32 # v1
with:
config: ${{ secrets.KUBE_CONFIG_DATA }}
command: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sync-version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: main
fetch-depth: 0 # Need full history for tag operations
Expand Down
44 changes: 12 additions & 32 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,28 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
enable-cache: true

- id: setup-python
name: Set up Python 3.13
uses: actions/setup-python@v5
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: 3.13

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 2.1.3
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true

# Only when the context is exactly the same, we will restore the cache.
- name: Load cached venv
id: restore-poetry-dependencies
uses: actions/cache/restore@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Create venv and install dependencies
if: steps.restore-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --with dev

- id: cache-poetry-dependencies
name: Cache venv
if: steps.restore-poetry-dependencies.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
run: uv sync --dev

- name: Run tests with pytest and generate coverage report
run: |
ENV_PATH=".test.env" poetry run task test
poetry run task coverage xml
ENV_PATH=".test.env" uv run task test
uv run task coverage xml

- name: Upload coverage reports to CodeCov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
38 changes: 6 additions & 32 deletions Dockerfile.base
Original file line number Diff line number Diff line change
@@ -1,52 +1,26 @@
ARG APP_NAME=hackster
ARG PYTHON_VERSION=3.13.9
ARG PYTHON_VERSION=3.13

# `python-base` sets up all our shared environment variables
FROM python:${PYTHON_VERSION}-slim AS python-base

# Poetry version used in this stage
ARG POETRY_VERSION=2.1.3
FROM astral/uv:python${PYTHON_VERSION}-bookworm-slim AS builder-base

# python
ENV \
# immediately dumped to the stream instead of being buffered.
PYTHONUNBUFFERED=1 \
# prevents python creating .pyc files
PYTHONDONTWRITEBYTECODE=1 \
# pip
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
# poetry
# https://python-poetry.org/docs/configuration/#using-environment-variables
POETRY_VERSION=$POETRY_VERSION \
# make poetry install to this location
POETRY_HOME="/opt/poetry" \
# make poetry create the virtual environment in the project's root
# it gets named `.venv`
POETRY_VIRTUALENVS_IN_PROJECT=true \
# do not ask any interactive question
POETRY_NO_INTERACTION=1
PYTHONDONTWRITEBYTECODE=1
ENV APP_PATH="/opt/hackster"

# `builder-base` stage is used to build deps + create our virtual environment
FROM python-base AS builder-base
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
# deps for installing poetry
curl \
# deps for building python deps
build-essential

# install poetry - respects $POETRY_VERSION & $POETRY_HOME
RUN curl -sSL https://install.python-poetry.org | python
ENV PATH="$POETRY_HOME/bin:$PATH"

# copy project requirement files here to ensure they will be cached.
WORKDIR $APP_PATH
COPY ./poetry.lock ./pyproject.toml ./
COPY ./uv.lock ./pyproject.toml ./

# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally
RUN poetry install --no-cache --without dev
# install runtime deps
RUN uv sync --frozen --no-dev --no-install-project
ENV VENV_PATH="$APP_PATH/.venv"
ENV PATH="$VENV_PATH/bin:$PATH"
2 changes: 1 addition & 1 deletion Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ COPY src ./src
COPY resources ./resources
COPY startup.sh ./startup.sh
COPY pyproject.toml ./pyproject.toml
COPY poetry.lock ./poetry.lock
COPY uv.lock ./uv.lock
RUN chmod +x ./startup.sh

ENV PYTHONPATH=$APP_PATH
Expand Down
104 changes: 50 additions & 54 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,62 @@
name = "hackster"
version = "1.9.0"
description = "Awesome hackster created by Hack The Box"
requires-python = ">=3.13"
authors = [
{name = "dimoschi", email = "dimos@hackthebox.eu"},
{name = "makelarisjr", email = "makelarisjr@hackthebox.eu"},
{name = "0xEmma", email = "emma@hackthebox.eu"},
{ name = "dimoschi", email = "dimos@hackthebox.eu" },
{ name = "makelarisjr", email = "makelarisjr@hackthebox.eu" },
{ name = "0xEmma", email = "emma@hackthebox.eu" },
]
maintainers = [
{name = "dimoschi", email = "dimos@hackthebox.eu"},
{name = "makelarisjr", email = "makelarisjr@hackthebox.eu"},
{ name = "dimoschi", email = "dimos@hackthebox.eu" },
{ name = "makelarisjr", email = "makelarisjr@hackthebox.eu" },
]
license = "MIT"
requires-python = ">=3.13"
dynamic = ["dependencies"]

[tool.poetry]
package-mode = false
license = { text = "MIT" }

[tool.poetry.dependencies]
python = "^3.13"
aiodns = "^3.0.0"
arrow = "^1.2.3"
py-cord = "^2.4.1"
pydantic = { extras = ["dotenv"], version = "^1.10.7" }
taskipy = "^1.10.4"
sqlalchemy = { extras = ["asyncio"], version = "^2.0.9" }
bcrypt = "^4.0.1"
asyncmy = "^0.2.7"
fastapi = "^0.120.3"
sentry-sdk = { extras = ["sqlalchemy"], version = "^2.8.0" }
alembic = "^1.10.3"
pymysql = "^1.1.1"
prometheus-client = "^0.16.0"
toml = "^0.10.2"
slack-sdk = "^3.27.1"
hypercorn = "^0.17.3"
audioop-lts = "^0.2.2"

[tool.poetry.group.dev.dependencies]
colorlog = "^6.5.0"
coverage = "^7.2"
flake8 = "^6.0"
flake8-annotations = "^3.0"
flake8-bugbear = "^23.3"
flake8-docstrings = "^1.6.0"
flake8-isort = "^6.0"
flake8-string-format = "^0.3.0"
flake8-tidy-imports = "^4.8.0"
flake8-todo = "^0.7"
pep8-naming = "^0.13"
pre-commit = "^3.2"
pytest = "^7.1.2"
pytest-asyncio = "^0.21"
python-dotenv = "^1.0"
ipython = "^8.12.0"
ipdb = "^0.13.13"
aioresponses = "^0.7.4"
pytest-mock = "^3.10.0"
dependencies = [
"aiodns>=3.0.0,<4.0.0",
"arrow>=1.2.3,<2.0.0",
"py-cord>=2.4.1,<3.0.0",
"pydantic[dotenv]>=1.10.7,<2.0.0",
"taskipy>=1.10.4,<2.0.0",
"sqlalchemy[asyncio]>=2.0.9,<3.0.0",
"bcrypt>=4.0.1,<5.0.0",
"asyncmy>=0.2.7,<0.3.0",
"fastapi>=0.120.3,<0.121.0",
"sentry-sdk[sqlalchemy]>=2.8.0,<3.0.0",
"alembic>=1.10.3,<2.0.0",
"pymysql>=1.1.1,<2.0.0",
"prometheus-client>=0.16.0,<1.0.0",
"toml>=0.10.2,<0.11.0",
"slack-sdk>=3.27.1,<4.0.0",
"hypercorn>=0.17.3,<0.18.0",
"audioop-lts>=0.2.2,<0.3.0",
"aiohttp>=3.13.3",
"urllib3>=2.6.3",
]

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[dependency-groups]
dev = [
"colorlog>=6.5.0,<7.0.0",
"coverage>=7.2,<8.0.0",
"flake8>=6.0,<7.0.0",
"flake8-annotations>=3.0,<4.0.0",
"flake8-bugbear>=23.3,<26.0.0",
"flake8-docstrings>=1.6.0,<2.0.0",
"flake8-isort>=6.0,<7.0.0",
"flake8-string-format>=0.3.0,<0.4.0",
"flake8-tidy-imports>=4.8.0,<5.0.0",
"flake8-todo>=0.7,<0.8.0",
"pep8-naming>=0.13,<1.0.0",
"pre-commit>=3.2,<5.0.0",
"pytest>=7.1.2,<8.0.0",
"pytest-asyncio>=0.21,<0.22.0",
"python-dotenv>=1.0,<2.0.0",
"ipython>=8.12.0,<9.0.0",
"ipdb>=0.13.13,<0.14.0",
"aioresponses>=0.7.4,<0.8.0",
"pytest-mock>=3.10.0,<4.0.0",
]

[tool.taskipy.tasks]
start = "python -m src"
Expand Down
Loading
Loading