diff --git a/.github/workflows/upgrade-deps.yml b/.github/workflows/upgrade-deps.yml
index 05def8817a..bac9e90122 100644
--- a/.github/workflows/upgrade-deps.yml
+++ b/.github/workflows/upgrade-deps.yml
@@ -24,7 +24,7 @@ jobs:
- name: Upgrade JS dependencies
# prettier-ignore
run: >
- docker-compose run --no-deps web /bin/sh -c '
+ docker compose run --no-deps web /bin/sh -c '
rm -f yarn.lock &&
chown -R $(whoami):$(whoami) . &&
npx --yes yarn-upgrade-all
@@ -32,7 +32,7 @@ jobs:
- name: Upgrade Python dependencies
# prettier-ignore
run: >
- docker-compose run --no-deps web /bin/sh -c '
+ docker compose run --no-deps web /bin/sh -c '
pip install --upgrade pip pip-tools &&
pip-compile --upgrade -o requirements/prod.txt requirements/prod.in &&
pip-compile --upgrade -o requirements/dev.txt requirements/dev.in
diff --git a/.gitignore b/.gitignore
index a0a16c87c9..354d7ae18d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -77,9 +77,6 @@ docs/_build/
# Component library documentation
storybook-static/
-# pyenv
-.python-version
-
# celery beat schedule file
celerybeat-schedule
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000000..e4fba21835
--- /dev/null
+++ b/.python-version
@@ -0,0 +1 @@
+3.12
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 26e008026f..378432220a 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -9,7 +9,7 @@ version: 2
build:
os: ubuntu-20.04
tools:
- python: '3.9'
+ python: '3.12'
# You can also specify other tool versions:
# nodejs: "16"
# rust: "1.55"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 53ed105a7b..af254ff761 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -14,8 +14,8 @@ provided in [./docs/running.md](./docs/running.md).
To run these tests with Docker first run the following commands,
- docker-compose up -d
- docker-compose exec web bash
+ docker compose up -d
+ docker compose exec web bash
If you are not using Docker or are using the VS Code integrated terminal inside
the Docker container simply execute the commands in your project's root
diff --git a/Dockerfile b/Dockerfile
index 3e0ddeefb5..9fb3674801 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,7 +2,7 @@ ARG BUILD_ENV=development
ARG PROD_ASSETS
ARG OMNIOUT_TOKEN
FROM node:22 AS node_base
-FROM python:3.9
+FROM python:3.12
# Node and npm
COPY --from=node_base /usr/local/lib/node_modules /usr/local/lib/node_modules
diff --git a/derrick b/derrick
index d3d58835f4..78ae8fdbec 100755
--- a/derrick
+++ b/derrick
@@ -1,22 +1,22 @@
#!/bin/bash -e
function dcr {
- docker-compose run --rm web $@
+ docker compose run --rm web $@
}
function dcrq {
- docker-compose run --rm --no-deps web $@
+ docker compose run --rm --no-deps web $@
}
case "$1" in
"up")
- docker-compose up
+ docker compose up
;;
"down")
- docker-compose down
+ docker compose down
;;
"build")
- docker-compose build
+ docker compose build
;;
"manage")
dcr python manage.py "${@:2}"
@@ -49,7 +49,7 @@ case "$1" in
dcrq yarn test:js "${@:2}"
;;
"storybook")
- docker-compose run --rm --no-deps --service-ports web yarn storybook "${@:2}"
+ docker compose run --rm --no-deps --service-ports web yarn storybook "${@:2}"
;;
"add:js")
dcrq yarn add "${@:2}"
diff --git a/docs/running.md b/docs/running.md
index 63890641b9..98aeb970cb 100644
--- a/docs/running.md
+++ b/docs/running.md
@@ -7,9 +7,9 @@
## Making A Virtual Env
-MetaDeploy development requires Python v3.9. If `which python3.9` returns a
+MetaDeploy development requires Python v3.12. If `which python3.12` returns a
non-empty path, it's already installed and you can continue to the next step. If
-it returns nothing, then install Python v3.9 using `brew install python`, or
+it returns nothing, then install Python v3.12 using `brew install python`, or
from [Python.org](https://www.python.org/downloads/).
Assuming you're in the repo root, do the following to create a virtualenv (once
@@ -17,7 +17,7 @@ you have
[virtualenvwrapper](https://virtualenvwrapper.readthedocs.io/en/latest/)
installed locally):
- mkvirtualenv metadeploy --python=$(which python3.9)
+ mkvirtualenv metadeploy --python=$(which python3.12)
setvirtualenvproject
Install Python requirements:
diff --git a/docs/running_docker.md b/docs/running_docker.md
index 944a1df5f5..98f370a821 100644
--- a/docs/running_docker.md
+++ b/docs/running_docker.md
@@ -18,18 +18,18 @@ _You should see something like the following:_
: `Docker version 20.10.14, build a224086`
-The latest version of Docker Desktop comes with docker-compose installed. To
-verify you have successfully installed docker-compose, run:
+The latest version of Docker Desktop comes with docker compose installed. To
+verify you have successfully installed docker compose, run:
- docker-compose -v
+ docker compose -v
_You should see something like the following:_
Docker Compose version v2.5.1
-If docker-compose is not installed, visit
+If docker compose is not installed, visit
and follow the installation
-instructions to download docker-compose.
+instructions to download docker compose.
### Running MetaDeploy In Docker
@@ -106,17 +106,17 @@ a plan.
Code](#docker-development-using-vs-code).
-This next section assumes you have installed `docker` and `docker-compose`.
+This next section assumes you have installed `docker` and `docker compose`.
Additionally it assumes you have a `.env` file in the root directory of this
project, a template of variables needed can be found in `env.example`.
To configure and run your environment you must run two commands in the project
-root. Note that `docker-compose build` will take some significant time to build
+root. Note that `docker compose build` will take some significant time to build
the first time but will be much faster for subsequent builds. It is also
important to note that once you bring up the web application it will take a
minute or two to build.
- docker-compose build
+ docker compose build
## Running Your Docker Containers
@@ -125,16 +125,16 @@ and the creation of a default admin user.
If you would like to disable this functionality please add a
`DJANGO_SETTINGS_MODULE` environment variable in the web service section of the
-docker-compose file to set it from its default value (set in Dockerfile) from
+docker compose file to set it from its default value (set in Dockerfile) from
`config.settings.local` to `config.settings.production`. For examples of how to
-do this please see [setting docker-compose environment
+do this please see [setting docker compose environment
variables](https://docs.docker.com/compose/environment-variables/).
Then run the following command:
- docker-compose up -d
+ docker compose up -d
or
- docker-compose up (for debug mode)
+ docker compose up (for debug mode)
This command may take a few minutes to finish. Once it's done, visit
`localhost:8000/admin/login` and login with the following credentials if
@@ -149,27 +149,27 @@ account will not be created when `BUILD_ENV` is set to `production`.
## Docker Commands
-To stop your virtual containers run the following command (the docker-compose
+To stop your virtual containers run the following command (the docker compose
stop command will stop your containers, but it won't remove them):
- docker-compose stop
+ docker compose stop
To start your virtual containers run the following command:
- docker-compose start
+ docker compose start
To bring your virtual containers up for the first time run the following
command:
- docker-compose up -d
+ docker compose up -d
To bring your virtual containers down run the following command:
> **Note**
-> The docker-compose down command will stop your containers, but also removes
+> The docker compose down command will stop your containers, but also removes
the stopped containers as well as any networks that were created.
- docker-compose down
+ docker compose down
Removes stopped service containers. To remove your stopped containers enter the
following commands
@@ -178,28 +178,28 @@ following commands
> This will destroy anything that is in the virtual environment, however the
database data will persist
- docker-compose rm
+ docker compose rm
(then enter `y` when prompted. If you would like to clear the database as well
-include a -v flag i.e. `docker-compose down -v`)
+include a -v flag i.e. `docker compose down -v`)
To view all running services run the following command:
- docker-compose ps
+ docker compose ps
If you'd like to test something out manually in that test environment for any
reason you can run the following: In order to run relevant management commands
like `manage.py makemigrations`, or if you'd like to test something
out manually in that test environment for any reason you can run the following:
- docker-compose exec web bash
+ docker compose exec web bash
After this you will be inside of a linux commandline, and are free to test
around in your container.
Or you could directly run a command like this:
- docker-compose exec web python manage.py makemigrations
+ docker compose exec web python manage.py makemigrations
## Docker development using VS Code
@@ -212,19 +212,19 @@ extension pack.
Once you have the extension pack installed, when you open the MetaDeploy folder
in VS Code, you will be prompted to "Reopen in Container". Doing so will
-effectively run `docker-compose up` and reload your window, now running inside
+effectively run `docker compose up` and reload your window, now running inside
the Docker container. If you do not see the prompt, run the "Remote-Containers:
Open Folder in Container\..." command from the VS Code Command Palette to start
the Docker container.
A number of project-specific VS Code extensions will be automatically installed
for you within the Docker container. See `.devcontainer/devcontainer.json` and
-`.devcontainer/docker-compose.dev.yml` for Docker-specific VS Code settings.
+`.devcontainer/docker compose.dev.yml` for Docker-specific VS Code settings.
The first build will take a number of minutes, but subsequent builds will be
significantly faster.
-Similarly to the behavior of `docker-compose up`, VS Code automatically runs
+Similarly to the behavior of `docker compose up`, VS Code automatically runs
database migrations and starts the development server/watcher. To run any local
commands, open an
[integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal)
@@ -236,7 +236,7 @@ RUNNING.RST and CONTRIBUTING.RST):
$ yarn serve # start the development server/watcher
For any commands, when using the VS Code integrated terminal inside the Docker
-container, omit any `docker-compose run --rm web...` prefix, e.g.:
+container, omit any `docker compose run --rm web...` prefix, e.g.:
$ python manage.py promote_superuser
$ yarn test:js
diff --git a/metadeploy/api/tests/test_jobs.py b/metadeploy/api/tests/test_jobs.py
index 7b717f35e6..9531c0879e 100644
--- a/metadeploy/api/tests/test_jobs.py
+++ b/metadeploy/api/tests/test_jobs.py
@@ -25,6 +25,8 @@
enqueuer,
expire_preflights,
finalize_result,
+ JobLogStatus,
+ JobType,
preflight,
run_flows,
)
@@ -220,9 +222,9 @@ def test_finalize_result_worker_died(job_factory, caplog):
log_record = next(r for r in caplog.records if "interrupted" in r.message)
assert log_record.message == f"Job {job.id} interrupted by dyno restart"
- assert log_record.context["event"] == "job"
+ assert log_record.context["event"] == f"{JobType.JOB}"
assert log_record.context["context"] == "test-product/1.0/sample-plan"
- assert log_record.context["status"] == "terminated"
+ assert log_record.context["status"] == f"{JobLogStatus.TERMINATED}"
assert "duration" in log_record.context
@@ -243,9 +245,9 @@ def test_finalize_result_canceled_job(job_factory, caplog):
log_record = next(r for r in caplog.records if "canceled" in r.message)
assert log_record.message == f"Job {job.id} canceled"
- assert log_record.context["event"] == "job"
+ assert log_record.context["event"] == f"{JobType.JOB}"
assert log_record.context["context"] == "test-product/1.0/sample-plan"
- assert log_record.context["status"] == "canceled"
+ assert log_record.context["status"] == f"{JobLogStatus.CANCELED}"
assert "duration" in log_record.context
@@ -273,9 +275,9 @@ def test_finalize_result_preflight_worker_died(
log_record.message
== f"PreflightResult {preflight.id} interrupted by dyno restart"
)
- assert log_record.context["event"] == "preflight"
+ assert log_record.context["event"] == f"{JobType.PREFLIGHT}"
assert log_record.context["context"] == "test-product/1.0/sample-plan"
- assert log_record.context["status"] == "terminated"
+ assert log_record.context["status"] == f"{JobLogStatus.TERMINATED}"
assert "duration" in log_record.context
@@ -296,9 +298,9 @@ def test_finalize_result_preflight_failed(
log_record = next(r for r in caplog.records if "failed" in r.message)
assert log_record.message == f"PreflightResult {preflight.id} failed"
- assert log_record.context["event"] == "preflight"
+ assert log_record.context["event"] == f"{JobType.PREFLIGHT}"
assert log_record.context["context"] == "test-product/1.0/sample-plan"
- assert log_record.context["status"] == "failure"
+ assert log_record.context["status"] == f"{JobLogStatus.FAILURE}"
assert "duration" in log_record.context
@@ -322,9 +324,9 @@ def test_finalize_result_mdapi_error(job_factory, caplog):
log_record = next(r for r in caplog.records if "errored" in r.message)
assert log_record.message == f"Job {job.id} errored"
- assert log_record.context["event"] == "job"
+ assert log_record.context["event"] == f"{JobType.JOB}"
assert log_record.context["context"] == "test-product/1.0/sample-plan"
- assert log_record.context["status"] == "error"
+ assert log_record.context["status"] == f"{JobLogStatus.ERROR}"
assert "duration" in log_record.context
@@ -341,9 +343,9 @@ def test_finalize_result_job_success(job_factory, caplog):
log_record = next(r for r in caplog.records if "succeeded" in r.message)
assert log_record.message == f"Job {job.id} succeeded"
- assert log_record.context["event"] == "job"
+ assert log_record.context["event"] == f"{JobType.JOB}"
assert log_record.context["context"] == "test-product/1.0/sample-plan"
- assert log_record.context["status"] == "success"
+ assert log_record.context["status"] == f"{JobLogStatus.SUCCESS}"
assert "duration" in log_record.context
diff --git a/requirements/dev.txt b/requirements/dev.txt
index dd6e3af4c1..615e8f8a2a 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -1,5 +1,5 @@
#
-# This file is autogenerated by pip-compile with Python 3.9
+# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --output-file=requirements/dev.txt requirements/dev.in
@@ -52,10 +52,6 @@ docutils==0.16
# -c requirements/prod.txt
# myst-parser
# sphinx
-exceptiongroup==1.2.0
- # via
- # ipython
- # pytest
executing==2.0.1
# via stack-data
factory-boy==3.3.0
@@ -75,11 +71,6 @@ idna==3.4
# yarl
imagesize==1.4.1
# via sphinx
-importlib-metadata==6.8.0
- # via
- # -c requirements/prod.txt
- # build
- # sphinx
inflection==0.5.1
# via pytest-factoryboy
iniconfig==2.0.0
@@ -221,14 +212,6 @@ sqlparse==0.4.4
# django
stack-data==0.6.3
# via ipython
-tomli==2.0.1
- # via
- # black
- # build
- # coverage
- # pip-tools
- # pyproject-hooks
- # pytest
traitlets==5.14.1
# via
# ipython
@@ -236,15 +219,11 @@ traitlets==5.14.1
typing-extensions==4.7.1
# via
# -c requirements/prod.txt
- # asgiref
- # black
- # ipython
# pytest-factoryboy
urllib3==1.26.16
# via
# -c requirements/prod.txt
# requests
- # vcrpy
vcrpy==5.1.0
# via -r requirements/dev.in
wcwidth==0.2.13
@@ -255,10 +234,6 @@ wrapt==1.16.0
# via vcrpy
yarl==1.9.4
# via vcrpy
-zipp==3.17.0
- # via
- # -c requirements/prod.txt
- # importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# pip
diff --git a/requirements/prod.txt b/requirements/prod.txt
index d8849ab11a..ae74f3bf2b 100644
--- a/requirements/prod.txt
+++ b/requirements/prod.txt
@@ -1,5 +1,5 @@
#
-# This file is autogenerated by pip-compile with Python 3.9
+# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --output-file=requirements/prod.txt requirements/prod.in
@@ -9,9 +9,7 @@ aioredis==1.3.1
ansi2html==1.9.1
# via -r requirements/prod.in
appdirs==1.4.4
- # via
- # cumulusci
- # fs
+ # via fs
asgiref==3.7.2
# via
# channels
@@ -19,18 +17,14 @@ asgiref==3.7.2
# daphne
# django
async-timeout==4.0.3
- # via
- # aioredis
- # redis
+ # via aioredis
attrs==23.2.0
# via
# automat
# service-identity
# twisted
authlib==1.2.1
- # via
- # cumulusci
- # simple-salesforce
+ # via simple-salesforce
autobahn==23.6.2
# via daphne
automat==22.10.0
@@ -47,26 +41,18 @@ botocore==1.34.22
# s3transfer
certifi==2023.7.22
# via
- # cumulusci
# requests
# sentry-sdk
- # snowfakery
cffi==1.16.0
- # via
- # cryptography
- # cumulusci
+ # via cryptography
channels[daphne]==3.0.5
# via
# -r requirements/prod.in
- # channels
# channels-redis
channels-redis==3.4.1
# via -r requirements/prod.in
charset-normalizer==3.2.0
- # via
- # cumulusci
- # requests
- # snowfakery
+ # via requests
click==8.1.6
# via
# cumulusci
@@ -88,10 +74,9 @@ cryptography==41.0.7
# cumulusci
# pyjwt
# pyopenssl
- # secretstorage
# service-identity
# sfdo-template-helpers
-cumulusci==3.84.3
+cumulusci==4.0.1
# via -r requirements/prod.in
daphne==3.0.2
# via channels
@@ -119,7 +104,7 @@ django==4.2.9
# sfdo-template-helpers
django-allauth==0.60.1
# via -r requirements/prod.in
-django-binary-database-files==1.0.17
+django-binary-database-files==1.0.18
# via -r requirements/prod.in
django-colorfield==0.11.0
# via -r requirements/prod.in
@@ -151,7 +136,7 @@ djangorestframework==3.14.0
# via
# -r requirements/prod.in
# sfdo-template-helpers
-docutils==0.16
+docutils==0.21.2
# via cumulusci
faker==19.3.0
# via
@@ -160,13 +145,9 @@ faker==19.3.0
# faker-nonprofit
# snowfakery
faker-edu==1.0.0
- # via
- # cumulusci
- # snowfakery
+ # via snowfakery
faker-nonprofit==1.0.0
- # via
- # cumulusci
- # snowfakery
+ # via snowfakery
freezegun==1.4.0
# via rq-scheduler
fs==2.4.16
@@ -175,14 +156,8 @@ github3-py==4.0.1
# via
# -r requirements/prod.in
# cumulusci
-greenlet==3.0.1
- # via
- # cumulusci
- # sqlalchemy
gvgen==1.0
- # via
- # cumulusci
- # snowfakery
+ # via snowfakery
hashids==1.3.1
# via django-hashid-field
hiredis==2.3.2
@@ -197,23 +172,13 @@ hyperlink==21.0.0
# twisted
idna==3.4
# via
- # cumulusci
# hyperlink
# requests
- # snowfakery
# twisted
importlib-metadata==6.8.0
- # via
- # cumulusci
- # keyring
- # markdown
+ # via keyring
incremental==22.10.0
# via twisted
-jeepney==0.8.0
- # via
- # cumulusci
- # keyring
- # secretstorage
jinja2==3.1.2
# via
# cumulusci
@@ -233,25 +198,18 @@ lxml==4.9.3
markdown==3.5.2
# via sfdo-template-helpers
markdown-it-py==2.2.0
- # via
- # cumulusci
- # rich
+ # via rich
markupsafe==2.1.3
# via
# cumulusci
# jinja2
- # snowfakery
# werkzeug
mdurl==0.1.2
- # via
- # cumulusci
- # markdown-it-py
+ # via markdown-it-py
msgpack==1.0.7
# via channels-redis
natsort==8.4.0
- # via
- # cumulusci
- # robotframework-pabot
+ # via robotframework-pabot
oauthlib==3.2.2
# via requests-oauthlib
packaging==23.2
@@ -271,29 +229,22 @@ pyasn1==0.5.1
pyasn1-modules==0.3.0
# via service-identity
pycparser==2.21
- # via
- # cffi
- # cumulusci
+ # via cffi
pydantic==1.10.12
# via
# cumulusci
# snowfakery
pygments==2.17.2
- # via
- # cumulusci
- # rich
+ # via rich
pyjwt[crypto]==2.8.0
# via
# cumulusci
# django-allauth
# github3-py
- # pyjwt
pyopenssl==23.3.0
# via twisted
python-baseconv==1.2.2
- # via
- # cumulusci
- # snowfakery
+ # via snowfakery
python-dateutil==2.8.2
# via
# botocore
@@ -334,7 +285,7 @@ requests-futures==1.0.1
# via cumulusci
requests-oauthlib==1.3.1
# via django-allauth
-rich==13.7.0
+rich==13.9.4
# via cumulusci
robotframework==6.1.1
# via
@@ -346,17 +297,13 @@ robotframework==6.1.1
robotframework-pabot==2.16.0
# via cumulusci
robotframework-pythonlibcore==4.3.0
- # via
- # cumulusci
- # robotframework-seleniumlibrary
+ # via robotframework-seleniumlibrary
robotframework-requests==0.9.6
# via cumulusci
robotframework-seleniumlibrary==5.1.3
# via cumulusci
robotframework-stacktrace==0.4.1
- # via
- # cumulusci
- # robotframework-pabot
+ # via robotframework-pabot
rq==1.15.1
# via
# -r requirements/prod.in
@@ -373,10 +320,6 @@ salesforce-bulk==2.2.0
# via cumulusci
sarge==0.1.7.post1
# via cumulusci
-secretstorage==3.3.3
- # via
- # cumulusci
- # keyring
selenium==3.141.0
# via
# cumulusci
@@ -397,12 +340,10 @@ six==1.16.0
# via
# automat
# bleach
- # cumulusci
# fs
# python-dateutil
# salesforce-bulk
- # snowfakery
-snowfakery==3.6.1
+snowfakery==4.0.0
# via cumulusci
sqlalchemy==1.4.49
# via
@@ -411,34 +352,23 @@ sqlalchemy==1.4.49
sqlparse==0.4.4
# via django
twisted[tls]==23.10.0
- # via
- # daphne
- # twisted
+ # via daphne
txaio==23.1.1
# via autobahn
typing-extensions==4.7.1
# via
- # asgiref
- # cumulusci
# pydantic
- # snowfakery
# twisted
unicodecsv==0.14.1
- # via
- # cumulusci
- # salesforce-bulk
+ # via salesforce-bulk
uritemplate==4.1.1
- # via
- # cumulusci
- # github3-py
+ # via github3-py
urllib3==1.26.16
# via
# botocore
- # cumulusci
# requests
# selenium
# sentry-sdk
- # snowfakery
webencodings==0.5.1
# via bleach
werkzeug==3.0.1
@@ -448,9 +378,7 @@ whitenoise==6.6.0
xmltodict==0.13.0
# via cumulusci
zipp==3.17.0
- # via
- # cumulusci
- # importlib-metadata
+ # via importlib-metadata
zope-interface==6.1
# via twisted
diff --git a/runtime.txt b/runtime.txt
deleted file mode 100644
index c6f7782f61..0000000000
--- a/runtime.txt
+++ /dev/null
@@ -1 +0,0 @@
-python-3.9.13