Merge branch 'pypi' into 'master'

pypi release prep!

See merge request engineering/make-post-sell/make_post_sell!39
This commit is contained in:
Russell Ballestrini 2025-03-02 13:54:38 +00:00
commit ca34177f28
4 changed files with 231 additions and 90 deletions

View file

@ -2,10 +2,13 @@ stages:
- test - test
- build - build
- deploy - deploy
- pypi-twine
test: test:
stage: test stage: test
tags: ["build"] tags: ["build"]
except:
- tags
script: make test script: make test
artifacts: artifacts:
paths: paths:
@ -15,22 +18,24 @@ test:
build: build:
stage: build stage: build
tags: ["build"] tags: ["build"]
except:
- tags
script: script:
- mv env.vanilla env - mv env.vanilla env
- make prod - make install-from-source-prod
# copy static assets to env/static & create a tarball of the static files. # Copy static assets to env/static and create a tarball of the static files.
- cp -pr make_post_sell/static env/static - cp -pr make_post_sell/static env/static
- cp -pr env/static static - cp -pr env/static static
- tar -zcf static.tar.gz static - tar -zcf static.tar.gz static
# move the virtualenv with virtualenv-clone into desired location. # Clone the virtualenv with virtualenv-clone into the desired location.
- virtualenv-clone env /opt/make_post_sell/env - virtualenv-clone env /opt/make_post_sell/env
# make tarball of virtualenv. # Create a tarball of the virtualenv.
- tar -zcf env.tar.gz -C /opt/make_post_sell . - tar -zcf env.tar.gz -C /opt/make_post_sell .
# create sha512 of env.tar.gz # Create SHA512 hash of env.tar.gz.
- sha512sum env.tar.gz >> env.tar.gz.hash - sha512sum env.tar.gz >> env.tar.gz.hash
# create commit-hash.txt to track this build's git commit hash. # Create commit-hash.txt to track this build's git commit hash.
- echo $CI_COMMIT_SHA >> commit-hash.txt - echo $CI_COMMIT_SHA >> commit-hash.txt
# clean up directory outside of gitlab-runner filesystem. # Clean up the directory outside of the gitlab-runner filesystem.
- rm -rf /opt/make_post_sell/env - rm -rf /opt/make_post_sell/env
artifacts: artifacts:
paths: paths:
@ -44,9 +49,19 @@ deploy:
stage: deploy stage: deploy
needs: [build] needs: [build]
rules: rules:
- if: '$CI_COMMIT_BRANCH == "develop"' - if: '$CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "main"'
when: on_success
- if: '$CI_COMMIT_BRANCH == "master"'
when: on_success when: on_success
trigger: trigger:
include: .gitlab-ci.deploy.yml include: .gitlab-ci.deploy.yml
pypi-twine:
stage: pypi-twine
tags:
- build
only:
- tags
script:
- pip install --upgrade pip
- pip install twine
- python3 setup.py sdist bdist_wheel
- twine upload dist/*

149
Makefile
View file

@ -1,31 +1,128 @@
env: # Makefile for operating the make_post_sell server using either PyPI packages or source
python3 -m venv env
. env/bin/activate
env/bin/pip install --upgrade pip
env/bin/pip install --upgrade -r requirements.py3.txt
dev: env # Variables (using the current working directory)
env/bin/pip install --upgrade -r requirements-dev.txt VENV_DIR = $(shell pwd)/env
env/bin/pip install --upgrade -r requirements-test.txt DATA_DIR = $(shell pwd)/data
env/bin/pip install --editable . CONFIG_FILE = development.ini
cp -rp env env.vanilla # Using the provided configuration URL.
CONFIG_URL = https://git.unturf.com/engineering/make-post-sell/make_post_sell/-/raw/master/development.ini
prod: env PYTHON = $(VENV_DIR)/bin/python
env/bin/pip install --upgrade -r requirements-prod.txt PIP = $(VENV_DIR)/bin/pip
env/bin/pip install . PSERVE = $(VENV_DIR)/bin/pserve
cp -rp env env.vanilla ALEMBIC = $(VENV_DIR)/bin/alembic
MPS_INIT = $(VENV_DIR)/bin/initialize_make_post_sell_db
init_db: env # Default target: install from PyPI and then start the server.
env/bin/initialize_make_post_sell_db ${config} all: install-from-pypi serve
# -----------------------------------------------------------------------------
# Environment Setup Targets
# -----------------------------------------------------------------------------
# Create virtual environment if not present.
$(VENV_DIR)/bin/activate:
@echo "Creating virtual environment in $(VENV_DIR)..."
python3 -m venv $(VENV_DIR)
venv: $(VENV_DIR)/bin/activate
# Create data directory and download configuration file if missing.
$(DATA_DIR)/$(CONFIG_FILE):
@echo "Creating data directory in $(DATA_DIR) and downloading configuration file..."
mkdir -p $(DATA_DIR)
cd $(DATA_DIR) && wget -O $(CONFIG_FILE) $(CONFIG_URL)
config: $(DATA_DIR)/$(CONFIG_FILE)
# -----------------------------------------------------------------------------
# Package Installation Targets for PyPI Installation
# -----------------------------------------------------------------------------
# Install the make_post_sell core package from PyPI.
install-core: venv
@echo "Installing make_post_sell core package from PyPI..."
$(PIP) install make_post_sell
# Install development extras from PyPI.
install-dev: venv
@echo "Installing make_post_sell development extras from PyPI..."
$(PIP) install make_post_sell[dev]
# Combined PyPI installation target.
install: install-core install-dev
# -----------------------------------------------------------------------------
# Package Installation Targets for Source Installation
# -----------------------------------------------------------------------------
# Install from source (editable mode) for development and testing.
install-source-dev-and-test: venv
@echo "Installing make_post_sell from source (editable mode) for development..."
$(PIP) install --editable .
$(PIP) install --upgrade -r requirements-dev.txt
$(PIP) install --upgrade -r requirements-test.txt
cp -rp $(VENV_DIR) $(VENV_DIR).vanilla
# Install from source for production (noneditable).
install-source-prod: venv
@echo "Installing make_post_sell from source for production (noneditable)..."
$(PIP) install .
$(PIP) install --upgrade -r requirements-prod.txt
cp -rp $(VENV_DIR) $(VENV_DIR).vanilla
# -----------------------------------------------------------------------------
# Database Initialization and Server Targets
# -----------------------------------------------------------------------------
# Initialize the database using the configuration file.
init-db: venv config
@echo "Initializing the make_post_sell database..."
$(MPS_INIT) $(DATA_DIR)/$(CONFIG_FILE)
$(ALEMBIC) -c $(DATA_DIR)/$(CONFIG_FILE) stamp head
# Start the development server with auto-reload.
serve: venv config
@echo "Starting the make_post_sell development server..."
$(PSERVE) $(DATA_DIR)/$(CONFIG_FILE) --reload
# -----------------------------------------------------------------------------
# Combined Setup Targets
# -----------------------------------------------------------------------------
# Install and set up using PyPI packages.
install-from-pypi: venv config install init-db
# Install and set up from source (editable mode) for development and testing.
install-from-source: venv config install-source-dev-and-test init-db
# Install and set up from source for production (noneditable).
install-from-source-prod: venv config install-source-prod init-db
# -----------------------------------------------------------------------------
# Additional Targets
# -----------------------------------------------------------------------------
# Print instructions for activating the virtual environment.
activate:
@echo "To activate the virtual environment, run:"
@echo " source $(VENV_DIR)/bin/activate"
# Run the test suite.
test: install-source-dev-and-test
@echo "Running tests..."
$(VENV_DIR)/bin/py.test
# Start a simple HTTP server (if needed for static files).
http: venv
@echo "Starting simple HTTP server on port 8000..."
$(PYTHON) -m http.server 8000
# -----------------------------------------------------------------------------
# Cleanup Target
# -----------------------------------------------------------------------------
# Remove the virtual environment directories.
clean: clean:
rm -rf env @echo "Cleaning up: removing $(VENV_DIR) and $(VENV_DIR).vanilla..."
rm -rf env.vanilla rm -rf $(VENV_DIR) $(VENV_DIR).vanilla
test: dev
#env/bin/py.test --lf
env/bin/py.test
serve: dev
# In the first shell, run a copy of make_post_sell using:
env/bin/pserve development.ini --reload

View file

@ -3,32 +3,51 @@ Make Post Sell
The `Make Post Sell <https://www.makepostsell.com>`_ monolith platform service. The `Make Post Sell <https://www.makepostsell.com>`_ monolith platform service.
You can use the SaaS or self-host!
Getting Started Our `blog acts as our user guide <https://blog.makepostsell.com/>`_ & also uses ``make_post_sell``!
---------------
Clone this repo and change your working directory to the checkout.
Create a Python virtual environment and install project dependencies: Quick Start: Operating a Server with PyPI or Source Code
==========================================================
.. code-block:: bash Before you start, navigate to the directory where you want to install ``make_post_sell`` database & files.
make dev This Makefile-based workflow lets you choose between installing ``make_post_sell`` from PyPI packages or directly from the source code (editable mode). Both flows create a virtual environment in ``./env`` and store configuration and SQLite data in the persistent ``./data`` directory.
Load schema and default data into the database using a script, 1. **Install make_post_sell**
we currently use sqlite3 as a development and test database:
.. code-block:: bash - **PyPI Installation:**
Download the Makefile and run::
wget "https://git.unturf.com/engineering/make-post-sell/make_post_sell/-/raw/master/Makefile"
make install-from-pypi
make init_db config=development.ini - **Source Installation (Editable Mode):**
Clone the repository and run::
git clone ssh://git@git.unturf.com:2222/engineering/make-post-sell/make_post_sell.git
make install-from-source
Run a web application server with the project loaded: - **Production Installation (NonEditable):**
For production use (noneditable even from source), run::
git clone ssh://git@git.unturf.com:2222/engineering/make-post-sell/make_post_sell.git
make install-from-source-prod
.. code-block:: bash 2. **Activate the Virtual Environment**
make serve Before running any commands, activate the virtual environment::
source env/bin/activate
In a web browser navagate to http://127.0.0.1:6501/ and you should see the app. 3. **Start the Development Server**
With the virtual environment active, start the server::
make serve
Then browse to `http://127.0.0.1:6501/ <http://127.0.0.1:6501/>`_ to view the app.
Running Tests Running Tests
@ -45,11 +64,6 @@ SQL Migrations
=============== ===============
If your deployment is brand new, you don't need to run any migrations. If your deployment is brand new, you don't need to run any migrations.
You should however run this to stamp the database as ready:
.. code-block:: bash
alembic -c development.ini stamp head
Otherwise, it should be safe to run this at anytime to catch your database up: Otherwise, it should be safe to run this at anytime to catch your database up:
@ -154,4 +168,3 @@ Licence
===================== =====================
All code contributed goes into the public domain. All code contributed goes into the public domain.

View file

@ -1,54 +1,70 @@
import os import os
from setuptools import setup, find_packages from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__)) def parse_requirements(filename):
with open(os.path.join(here, "README.rst")) as f: """
README = f.read() Read and parse a requirements file, ignoring comments and blank lines.
"""
req_path = os.path.join(os.path.dirname(__file__), filename)
with open(req_path, "r", encoding="utf-8") as f:
lines = f.read().splitlines()
return [line.strip() for line in lines if line.strip() and not line.startswith("#")]
tests_require = [ # Determine the runtime requirements.
"WebTest >= 1.3.1", # py3 compat install_requires = parse_requirements("requirements.py3.txt")
"pytest >= 3.7.4",
"pytest-cov", # Optional extras for development, production, and testing.
] extras_require = {
"dev": parse_requirements("requirements-dev.txt"),
"prod": parse_requirements("requirements-prod.txt"),
"test": parse_requirements("requirements-test.txt"),
}
# Read the long description from README.rst.
here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, "README.rst"), "r", encoding="utf-8") as f:
long_description = f.read()
setup( setup(
name="make_post_sell", name="make_post_sell",
version="1.0.0", version="1.0.0",
description="Make Post Sell", description="Make Post Sell",
long_description=README, long_description=long_description,
author="Russell Ballestrini",
author_email="russell@ballestrini.net",
url="https://www.makepostsell.com",
keywords="make post sell web pyramid pylons ecommerse digital downloads content marketing youtube alternative",
packages=find_packages(exclude="tests"),
package_data={
"make_post_sell": ["scripts/alembic/*.py", "scripts/alembic/versions/*.py"]
},
include_package_data=True,
zip_safe=False,
extras_require={
"testing": tests_require,
},
entry_points={
"paste.app_factory": [
"main = make_post_sell:main",
],
"console_scripts": [
"initialize_make_post_sell_db=make_post_sell.scripts.initialize_db:main",
],
},
classifiers=[ classifiers=[
"Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python", "Programming Language :: Python",
"Framework :: Pyramid", "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
], ],
author="Russell Ballestrini",
author_email="russell@ballestrini.net",
url="https://www.makepostsell.com",
keywords="make post sell web pyramid pylons ecommerce digital downloads physical goods content marketing youtube alternative",
packages=find_packages(),
package_data={
"make_post_sell": ["scripts/alembic/*.py", "scripts/alembic/versions/*.py"]
},
include_package_data=True,
zip_safe=False,
install_requires=install_requires,
extras_require=extras_require,
entry_points={
"paste.app_factory": ["main = make_post_sell:main"],
"console_scripts": [
"initialize_make_post_sell_db = make_post_sell.scripts.initialize_db:main",
],
},
) )
# python setup.py sdist bdist_wheel
# twine upload dist/*