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
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
OPENAI_API_KEY=ADD-YOUR-OPENAI_API_KEY-HERE
REPO_NAME=agentic-ai-workflow
DOCKERHUB_USERNAME=lpm0073

# These settings are probably fine to leave as-is.
ENVIRONMENT=local
DOCKERHUB_USERNAME=ADD-YOUR-DOCKERHUB_USERNAME-HERE
DOCKERHUB_ACCESS_TOKEN=ADD-YOUR-DOCKERHUB_ACCESS_TOKEN-HERE
LLM_TOOL_CHOICE=required
LOGGING_LEVEL=20
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@

.mypy_cache/

# my own homegrown file to store coverage report output from Docker.
coverage.out

Expand Down
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).



## [0.1.7](https://github.com/FullStackWithLawrence/agentic-ai-workflow/compare/v0.1.6...v0.1.7) (2026-05-21)


### Bug Fixes

* automated build and tear down ([fa572e2](https://github.com/FullStackWithLawrence/agentic-ai-workflow/commit/fa572e289f2fa737f9c30659e8f62303971aef50))

## [0.1.7](https://github.com/FullStackWithLawrence/agentic-ai-workflow/compare/v0.1.6...v0.1.7) (2026-05-21)


### Bug Fixes

* automated build and tear down ([fa572e2](https://github.com/FullStackWithLawrence/agentic-ai-workflow/commit/fa572e289f2fa737f9c30659e8f62303971aef50))

# Change Log

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.1.6](https://github.com/FullStackWithLawrence/agentic-ai-workflow/compare/v0.1.5...v0.1.6) (2026-04-02)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LABEL maintainer="Lawrence McDaniel <lpm0073@gmail.com>" \
license="GNU AGPL v3" \
vcs-url="https://github.com/FullStackWithLawrence/agentic-ai-workflow" \
org.opencontainers.image.title="StackademyAssistent" \
org.opencontainers.image.version="0.1.6" \
org.opencontainers.image.version="0.1.7" \
org.opencontainers.image.authors="Lawrence McDaniel <lpm0073@gmail.com>" \
org.opencontainers.image.url="https://FullStackWithLawrence.github.io/agentic-ai-workflow/" \
org.opencontainers.image.source="https://github.com/FullStackWithLawrence/agentic-ai-workflow" \
Expand Down
94 changes: 58 additions & 36 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
SHELL := /bin/bash
export PATH := /usr/local/bin:$(PATH)
export
# Windows‑optimized Makefile (cmd.exe as shell)

# Detect OS and set Python / venv activation / .env loading
ifeq ($(OS),Windows_NT)
PYTHON := python.exe
ACTIVATE_VENV := venv\Scripts\activate
PYTHON := python.exe
ACTIVATE_VENV := call venv\Scripts\activate
LOAD_ENV := for /f "usebackq tokens=1,2 delims==" %%a in (".env") do set %%a=%%b
else
PYTHON := python3.13
ACTIVATE_VENV := source venv/bin/activate
PYTHON := python3.13
ACTIVATE_VENV := . venv/bin/activate
LOAD_ENV := set -a && . .env && set +a
endif

PIP := $(PYTHON) -m pip

ifneq ("$(wildcard .env)","")
include .env
include .env
else
$(shell cp .env.example .env)
$(shell cp .env.example .env)
endif

.PHONY: analyze pre-commit init lint tear-down test build release
.PHONY: analyze pre-commit init init-dev lint tear-down test build release \
docker-build docker-run docker-test docker-coverage docker-push docker-prune

# Default target executed when no arguments are given to make.
all: help
Expand Down Expand Up @@ -71,21 +74,43 @@ lint:
flake8 ./app/
pylint ./app/**/*.py

# ---------------------------------------------------------
# tear down venv / node_modules (Windows + *nix)
# ---------------------------------------------------------
ifeq ($(OS),Windows_NT)
RM_VENV := if exist venv rmdir /S /Q venv
RM_NODE := if exist node_modules rmdir /S /Q node_modules
RM_PYCACHE := if exist app\__pycache__ rmdir /S /Q app\__pycache__
RM_LOCK := if exist package-lock.json del /F /Q package-lock.json
else
RM_VENV := rm -rf venv
RM_NODE := rm -rf node_modules
RM_PYCACHE := rm -rf app/__pycache__
RM_LOCK := rm -f package-lock.json
endif

tear-down:
rm -rf venv node_modules app/__pycache__ package-lock.json
$(RM_VENV)
$(RM_NODE)
$(RM_PYCACHE)
$(RM_LOCK)

docker-build:
docker build -t ${DOCKERHUB_USERNAME}/${REPO_NAME} . --build-arg ENVIRONMENT=${ENVIRONMENT}

# ---------------------------------------------------------
# Docker commands using .env (Windows: LOAD_ENV)
# ---------------------------------------------------------
docker-push:
source .env && \
$(LOAD_ENV) && \
docker tag ${DOCKERHUB_USERNAME}/${REPO_NAME} ${DOCKERHUB_USERNAME}/${REPO_NAME}:latest && \
echo "${DOCKERHUB_ACCESS_TOKEN}" | docker login --username=${DOCKERHUB_USERNAME} --password-stdin && \
docker push ${DOCKERHUB_USERNAME}/${REPO_NAME}:latest

docker-run:
source .env && \
docker run -it -e OPENAI_API_KEY=${OPENAI_API_KEY} \
$(LOAD_ENV) && \
docker run -it \
-e OPENAI_API_KEY=${OPENAI_API_KEY} \
-e ENVIRONMENT=prod \
-e MYSQL_HOST=${MYSQL_HOST} \
-e MYSQL_PORT=${MYSQL_PORT} \
Expand All @@ -97,7 +122,7 @@ docker-run:
-e LLM_TOOL_CHOICE=${LLM_TOOL_CHOICE} ${DOCKERHUB_USERNAME}/${REPO_NAME}:latest

docker-test:
source .env && \
$(LOAD_ENV) && \
docker run --rm \
-e OPENAI_API_KEY=${OPENAI_API_KEY} \
-e ENVIRONMENT=local \
Expand All @@ -113,7 +138,7 @@ docker-test:
python -m unittest discover -s app/

docker-coverage:
source .env && \
$(LOAD_ENV) && \
docker run --rm \
-e OPENAI_API_KEY=${OPENAI_API_KEY} \
-e ENVIRONMENT=local \
Expand All @@ -129,29 +154,26 @@ docker-coverage:
/bin/bash -c "python -m coverage run --source=app --omit='app/tests/*' -m unittest discover -s app/tests && python -m coverage report -m --omit='app/tests/*' && python -m coverage xml --omit='app/tests/*'"

docker-prune:
@if [ "`docker ps -aq`" ]; then \
docker stop $(docker ps -aq); \
fi
@docker container prune -f
@docker image prune -af
@docker builder prune -af
docker container prune -f
docker image prune -af
docker builder prune -af

######################
# HELP
######################
help:
@echo '===================================================================='
@echo 'analyze - generate code analysis report'
@echo 'release - force a new GitHub release'
@echo 'init - create a Python virtual environment and install prod dependencies'
@echo 'init-dev - install dev dependencies'
@echo 'test - run Python unit tests'
@echo 'lint - run Python linting'
@echo 'tear-down - destroy the Python virtual environment'
@echo 'pre-commit - install and run pre-commit hooks'
@echo 'docker-build - build the Docker image'
@echo 'docker-run - run the Docker image'
@echo 'docker-test - run the Docker image for testing'
@echo 'docker-coverage - run the Docker image for testing + coverage report'
@echo 'docker-push - push the Docker image to DockerHub'
@echo 'docker-prune - Docker tear-down containers/images/builders'
@echo 'analyze - generate code analysis report'
@echo 'release - force a new GitHub release'
@echo 'init - create a Python virtual environment and install prod dependencies'
@echo 'init-dev - install dev dependencies'
@echo 'test - run Python unit tests'
@echo 'lint - run Python linting'
@echo 'tear-down - destroy the Python virtual environment'
@echo 'pre-commit - install and run pre-commit hooks'
@echo 'docker-build - build the Docker image'
@echo 'docker-run - run the Docker image'
@echo 'docker-test - run the Docker image for testing'
@echo 'docker-coverage - run the Docker image for testing + coverage report'
@echo 'docker-push - push the Docker image to DockerHub'
@echo 'docker-prune - Docker tear-down containers/images/builders'
157 changes: 157 additions & 0 deletions Makefile_Original
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
SHELL := /bin/bash
export PATH := /usr/local/bin:$(PATH)
export

ifeq ($(OS),Windows_NT)
PYTHON := python.exe
ACTIVATE_VENV := venv\Scripts\activate
else
PYTHON := python3.13
ACTIVATE_VENV := source venv/bin/activate
endif
PIP := $(PYTHON) -m pip

ifneq ("$(wildcard .env)","")
include .env
else
$(shell cp .env.example .env)
endif

.PHONY: analyze pre-commit init lint tear-down test build release

# Default target executed when no arguments are given to make.
all: help

analyze:
cloc . --exclude-ext=svg,json,zip --vcs=git

release:
git commit -m "fix: force a new release" --allow-empty && git push

# -------------------------------------------------------------------------
# Install and run pre-commit hooks
# -------------------------------------------------------------------------
pre-commit:
pre-commit install
pre-commit autoupdate
pre-commit run --all-files

# ---------------------------------------------------------
# create python virtual environments for prod
# ---------------------------------------------------------
init:
make tear-down
$(PYTHON) -m venv venv && \
$(ACTIVATE_VENV) && \
$(PIP) install --upgrade pip && \
$(PIP) install -r requirements/base.txt

# ---------------------------------------------------------
# create python virtual environments for dev
# ---------------------------------------------------------
init-dev:
make init && \
npm install && \
$(ACTIVATE_VENV) && \
$(PIP) install -r requirements/local.txt && \
pre-commit install

test:
python -m unittest discover -s app/

coverage:
python -m coverage run --source=app --omit='app/tests/*' -m unittest discover -s app/tests
python -m coverage report -m --omit='app/tests/*'
python -m coverage xml --omit='app/tests/*'

lint:
isort .
pre-commit run --all-files
black .
flake8 ./app/
pylint ./app/**/*.py

tear-down:
rm -rf venv node_modules app/__pycache__ package-lock.json

docker-build:
docker build -t ${DOCKERHUB_USERNAME}/${REPO_NAME} . --build-arg ENVIRONMENT=${ENVIRONMENT}

docker-push:
source .env && \
docker tag ${DOCKERHUB_USERNAME}/${REPO_NAME} ${DOCKERHUB_USERNAME}/${REPO_NAME}:latest && \
echo "${DOCKERHUB_ACCESS_TOKEN}" | docker login --username=${DOCKERHUB_USERNAME} --password-stdin && \
docker push ${DOCKERHUB_USERNAME}/${REPO_NAME}:latest

docker-run:
source .env && \
docker run -it -e OPENAI_API_KEY=${OPENAI_API_KEY} \
-e ENVIRONMENT=prod \
-e MYSQL_HOST=${MYSQL_HOST} \
-e MYSQL_PORT=${MYSQL_PORT} \
-e MYSQL_USER=${MYSQL_USER} \
-e MYSQL_PASSWORD=${MYSQL_PASSWORD} \
-e MYSQL_DATABASE=${MYSQL_DATABASE} \
-e MYSQL_CHARSET=${MYSQL_CHARSET} \
-e LOGGING_LEVEL=${LOGGING_LEVEL} \
-e LLM_TOOL_CHOICE=${LLM_TOOL_CHOICE} ${DOCKERHUB_USERNAME}/${REPO_NAME}:latest

docker-test:
source .env && \
docker run --rm \
-e OPENAI_API_KEY=${OPENAI_API_KEY} \
-e ENVIRONMENT=local \
-e MYSQL_HOST=${MYSQL_HOST} \
-e MYSQL_PORT=${MYSQL_PORT} \
-e MYSQL_USER=${MYSQL_USER} \
-e MYSQL_PASSWORD=${MYSQL_PASSWORD} \
-e MYSQL_DATABASE=${MYSQL_DATABASE} \
-e MYSQL_CHARSET=${MYSQL_CHARSET} \
-e LOGGING_LEVEL=${LOGGING_LEVEL} \
-e LLM_TOOL_CHOICE=${LLM_TOOL_CHOICE} \
${DOCKERHUB_USERNAME}/${REPO_NAME}:latest \
python -m unittest discover -s app/

docker-coverage:
source .env && \
docker run --rm \
-e OPENAI_API_KEY=${OPENAI_API_KEY} \
-e ENVIRONMENT=local \
-e MYSQL_HOST=${MYSQL_HOST} \
-e MYSQL_PORT=${MYSQL_PORT} \
-e MYSQL_USER=${MYSQL_USER} \
-e MYSQL_PASSWORD=${MYSQL_PASSWORD} \
-e MYSQL_DATABASE=${MYSQL_DATABASE} \
-e MYSQL_CHARSET=${MYSQL_CHARSET} \
-e LOGGING_LEVEL=${LOGGING_LEVEL} \
-e LLM_TOOL_CHOICE=${LLM_TOOL_CHOICE} \
${DOCKERHUB_USERNAME}/${REPO_NAME}:latest \
/bin/bash -c "python -m coverage run --source=app --omit='app/tests/*' -m unittest discover -s app/tests && python -m coverage report -m --omit='app/tests/*' && python -m coverage xml --omit='app/tests/*'"

docker-prune:
@if [ -n "$$(docker ps -aq)" ]; then \
docker stop $$(docker ps -aq); \
fi
@docker container prune -f
@docker image prune -af
@docker builder prune -af

######################
# HELP
######################
help:
@echo '===================================================================='
@echo 'analyze - generate code analysis report'
@echo 'release - force a new GitHub release'
@echo 'init - create a Python virtual environment and install prod dependencies'
@echo 'init-dev - install dev dependencies'
@echo 'test - run Python unit tests'
@echo 'lint - run Python linting'
@echo 'tear-down - destroy the Python virtual environment'
@echo 'pre-commit - install and run pre-commit hooks'
@echo 'docker-build - build the Docker image'
@echo 'docker-run - run the Docker image'
@echo 'docker-test - run the Docker image for testing'
@echo 'docker-coverage - run the Docker image for testing + coverage report'
@echo 'docker-push - push the Docker image to DockerHub'
@echo 'docker-prune - Docker tear-down containers/images/builders'
2 changes: 1 addition & 1 deletion app/__version__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# DO NOT EDIT.
# Managed via automated CI/CD in .github/workflows/semanticVersionBump.yml.
__version__ = "0.1.6"
__version__ = "0.1.7"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "StackademyAI"
version = "0.1.6"
version = "0.1.7"
requires-python = ">=3.10"
description = "StackademyAI: an AI-powered marketing agent"
authors = [{ name = "Lawrence McDaniel", email = "lpm0073@gmail.com" }]
Expand Down
Loading