Skip to content

Commit

Permalink
👷(circleci) publish python package on every merge on master
Browse files Browse the repository at this point in the history
We use setuptools_scm to automatically generate the release version of
richie. When the current commit is a tag, the version tag will be used.
Otherwise it guess the next version number with unique info like the
current commit hash. The CI is refactor to take advantage of this
feature.
  • Loading branch information
lunika committed Jan 18, 2024
1 parent 961e70a commit c9e0ab4
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 65 deletions.
96 changes: 56 additions & 40 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ aliases:
command: |
sudo apt-get update
sudo apt-get install -y libcairo2-dev
jobs:
# Git jobs
# Check that the git history is clean and complies with our expectations
Expand Down Expand Up @@ -113,34 +114,6 @@ jobs:
name: Run renovate-config-validator command
command: renovate-config-validator

# Check that all versions (backend, frontend, website and cookiecutter) are up-to-date
check-versions:
docker:
- image: cimg/python:3.10
working_directory: ~/fun
steps:
- checkout
- run:
name: Check that all versions are the same
command: |
BACKEND_VERSION=$(python setup.py --version)
echo "richie version: ${BACKEND_VERSION}"
# In the frontend
cat src/frontend/package.json | grep "\"version\": \"${BACKEND_VERSION}\",$"
# In the cookiecutter site template backend
cat cookiecutter/{{cookiecutter.organization}}-richie-site-factory/template/{{cookiecutter.site}}/requirements/base.txt | grep "richie==${BACKEND_VERSION}$"
# In the cookiecutter site template frontend
cat cookiecutter/{{cookiecutter.organization}}-richie-site-factory/template/{{cookiecutter.site}}/src/frontend/package.json | grep "\"richie-education\": \"${BACKEND_VERSION}\"$"
# In the cookiecutter documentation
cat docs/cookiecutter.md | grep "cookiecutter gh:openfun/richie --directory cookiecutter --checkout v${BACKEND_VERSION}"
cat docs/cookiecutter.md | grep "fundocker/cookiecutter gh:openfun/richie --directory cookiecutter --checkout v${BACKEND_VERSION}"
# In the e2e tests
cat tests_e2e/package.json | grep "\"version\": \"${BACKEND_VERSION}\",$"
# In the website
cat website/package.json | grep "\"version\": \"${BACKEND_VERSION}\",$"
# In the website versions
cat website/versions.json | grep "\"${BACKEND_VERSION}\",$"
# ---- Docker jobs ----
# Build the Docker image ready for production
build-docker:
Expand Down Expand Up @@ -622,6 +595,51 @@ jobs:
~/.local/bin/pytest
# ---- Packaging jobs ----
check-versions:
docker:
- image: cimg/python:3.10-node
auth:
username: $DOCKER_USER
password: $DOCKER_PASS
working_directory: ~/fun
steps:
- checkout
- run:
name: check configured version
command: |
BRANCH_REGEX="release/v(.*)"
if [[ $CIRCLE_BRANCH =~ $BRANCH_REGEX ]]
then
VERSION="${BASH_REMATCH[1]}"
python -m pip install --upgrade setuptools_scm
BACKEND_VERSION=$(python -m setuptools_scm --strip-dev)
STABLE_VERSION_REGEX="^[0-9]*\.[0-9]*\.[0-9]*$"
if [[ $VERSION =~ $STABLE_VERSION_REGEX ]]; then
echo "Release of a stable version, front and back version must match. BACKEND_VERSION is set with VERSION variable"
BACKEND_VERSION=$VERSION
fi
echo "richie version: ${VERSION}"
echo "backend version: ${BACKEND_VERSION}"
# In the frontend
grep "\"version\": \"${VERSION}\",$" src/frontend/package.json
# In the cookiecutter site template backend
cat cookiecutter/{{cookiecutter.organization}}-richie-site-factory/template/{{cookiecutter.site}}/requirements/base.txt | grep "richie==${BACKEND_VERSION}$"
# In the cookiecutter site template frontend
cat cookiecutter/{{cookiecutter.organization}}-richie-site-factory/template/{{cookiecutter.site}}/src/frontend/package.json | grep "\"richie-education\": \"${VERSION}\"$"
# In the cookiecutter documentation
cat docs/cookiecutter.md | grep "cookiecutter gh:openfun/richie --directory cookiecutter --checkout v${VERSION}"
cat docs/cookiecutter.md | grep "fundocker/cookiecutter gh:openfun/richie --directory cookiecutter --checkout v${VERSION}"
# In the e2e tests
cat tests_e2e/package.json | grep "\"version\": \"${VERSION}\",$"
# In the website
cat website/package.json | grep "\"version\": \"${VERSION}\",$"
# In the website versions
cat website/versions.json | grep "\"${VERSION}\",$"
else
echo "branch name does not match pattern ${BRANCH_REGEX}"
exit 1
fi
package-back:
docker:
- image: cimg/python:3.10
Expand All @@ -637,7 +655,9 @@ jobs:
at: ~/fun
- run:
name: Build python package
command: python setup.py sdist bdist_wheel
command: |
python -m pip install --upgrade build
python -m build
# Persist build packages to the workspace
- persist_to_workspace:
root: ~/fun
Expand Down Expand Up @@ -904,7 +924,7 @@ jobs:
# environment variables in CircleCI UI (with your PyPI credentials)
npm:
docker:
- image: cimg/node:18.19
- image: cimg/python:3.10-node
auth:
username: $DOCKER_USER
password: $DOCKER_PASS
Expand All @@ -917,7 +937,7 @@ jobs:
- run:
name: Publish package
command: |
# If no tag is defined, this is a merge ofn master branch
# If no tag is defined, this is a merge on master branch
if [[ -n "$CIRCLE_TAG" ]]; then
python -m pip install --upgrade setuptools_scm
NEXT_VERSION=$(python -m setuptools_scm)
Expand Down Expand Up @@ -1038,12 +1058,6 @@ workflows:
filters:
tags:
only: /.*/
# Check on each PR if the last richie version is present everywhere it should be.
# If not the build will fail before publishing a new release.
- check-versions:
filters:
tags:
only: /.*/

# Docker jobs
#
Expand Down Expand Up @@ -1113,6 +1127,11 @@ workflows:
branches:
only: master

- check-versions:
filters:
branches:
only: /release\/v.*/

# Packaging: python
#
# Build the python package
Expand All @@ -1134,7 +1153,6 @@ workflows:
# succeed and it has been tagged with a tag starting with the letter v
- pypi:
requires:
- check-versions
- package-back
filters:
branches:
Expand All @@ -1148,7 +1166,6 @@ workflows:
# succeed and it has been tagged with a tag starting with the letter v
- npm:
requires:
- check-versions
- lint-front
- test-front
- test-front-package
Expand All @@ -1170,7 +1187,6 @@ workflows:
# documentation in the release commit on master before they go out.
- deploy-website:
requires:
- check-versions
- lint-website
filters:
branches:
Expand Down
4 changes: 3 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ __pycache__
**/*.pyc
venv
.venv
dist

# System-specific files
.DS_Store
Expand All @@ -22,8 +23,9 @@ docs
# Development/test cache & configurations
.cache
.circleci
.git
.vscode
# don't remove the line after, we need .git to build the sandbox image.
!.git

# Assets
data
Expand Down
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ COPY --from=front-builder \
# Upgrade pip to its latest release to speed up dependencies installation
RUN pip install --upgrade pip

RUN mkdir /install && \
RUN --mount=type=bind,source=.git,target=/builder/.git \
mkdir /install && \
pip install --prefix=/install .[sandbox]

# ---- Core application image ----
Expand Down Expand Up @@ -111,6 +112,9 @@ COPY . /app/
RUN pip uninstall -y richie
RUN pip install -e .[dev]

# Clean remaining .git files
RUN rm -rf .git*

# Restore the un-privileged user running the application
ARG DOCKER_USER
USER ${DOCKER_USER}
Expand Down
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# Richie package
#
[build-system]
requires = ["setuptools"]
requires = ["setuptools>=60", "setuptools-scm>=8.0"]
build-backend = "setuptools.build_meta"

[project]
name = "richie"
version = "2.25.0-beta.1"
dynamic = ["version"]
description = "A CMS to build learning portals for open education"
readme = "README.md"
authors = [{ "name" = "Open FUN (France Université Numérique)", "email" = "[email protected]" }]
Expand Down Expand Up @@ -42,6 +42,7 @@ dependencies = [
"easy_thumbnails[svg]>=2.8",
"elasticsearch>=6.0.0,<7.0.0",
"exrex==0.11.0",
"importlib-metadata",
"oauthlib==3.2.2",
"requests==2.31.0",
]
Expand Down Expand Up @@ -130,3 +131,5 @@ testpaths = [
filterwarnings = [
"ignore:::(?!(tests|richie))",
]

[tool.setuptools_scm]
23 changes: 2 additions & 21 deletions src/richie/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
"""
Richie: a FUN portal for Open edX
"""
from __future__ import absolute_import, unicode_literals
from importlib_metadata import version

import os

import pkg_resources
from setuptools.config import read_configuration

PROJECT_DIR = os.path.join(os.path.dirname(__file__), "../..")


def _extract_version(package_name):
"""
Get package version from installed distribution or configuration file if not
installed
"""
try:
return pkg_resources.get_distribution(package_name).version
except pkg_resources.DistributionNotFound:
_conf = read_configuration(os.path.join(PROJECT_DIR, "pyproject.toml"))
return _conf["project"]["version"]


__version__ = _extract_version("richie")
__version__ = version("richie")

0 comments on commit c9e0ab4

Please sign in to comment.