Skip to content

Commit a1c7b76

Browse files
authored
fix steps/job names in release workflows (#66)
* fix steps/job names * Update names and skip tests for now * fix build * update requirements * update wheel * remove docker build * pin python * update upload name * Update workflows * Update documentation * Update supported versions * Update version support * Update for deprecations * Fix tests/ci * remove setup_test_environment * Fix test failing in 5.2 * Update docs and fix test * Update supported versions * Drop support for python 3.7
1 parent 2a2025d commit a1c7b76

File tree

16 files changed

+172
-108
lines changed

16 files changed

+172
-108
lines changed

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
PYTHON_VERSION=3.9.9
2-
DJANGO_VERSION=4.0.1
1+
PYTHON_VERSION=3.12
2+
DJANGO_VERSION=5.2
33
SELENIUM_VERSION=4.0.0a7

.github/workflows/release-test.yml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Publish Python 🐍 distribution 📦 TestPyPI
1+
name: Test Release
22

33
on: workflow_dispatch
44

@@ -9,7 +9,7 @@ jobs:
99
lint:
1010
uses: ./.github/workflows/lint.yml
1111

12-
release-build:
12+
build:
1313
runs-on: ubuntu-latest
1414
needs:
1515
- run-tests
@@ -20,21 +20,22 @@ jobs:
2020

2121
- uses: actions/setup-python@v5
2222
with:
23-
python-version: "3.x"
23+
# Using with <3.13 since cgi was removed in 3.13
24+
python-version: "3.11"
2425

2526
- name: Build distribution 📦
2627
run: |
27-
docker compose -f docker-compose.ci.yml up -d --build
28+
pip install -r requirements.txt
2829
make package
2930
3031
- name: upload dists
3132
uses: actions/upload-artifact@v4
3233
with:
33-
name: release-dists
34+
name: python-package-distributions
3435
path: dist/
3536

3637
publish-to-testpypi:
37-
name: Publish Python 🐍 distribution 📦 to TestPyPI
38+
name: Publish to TestPyPI
3839
if: github.actor == 'trangpham'
3940
needs:
4041
- build
@@ -53,7 +54,7 @@ jobs:
5354
with:
5455
name: python-package-distributions
5556
path: dist/
56-
- name: Publish distribution 📦 to TestPyPI
57+
- name: Publish Python 🐍 distribution 📦 to TestPyPI
5758
uses: pypa/gh-action-pypi-publish@release/v1
5859
with:
5960
repository-url: https://test.pypi.org/legacy/

.github/workflows/release.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Publish Python 🐍 distribution 📦 to PyPI and Github
1+
name: Publish Release
22

33
on: workflow_dispatch
44

@@ -9,8 +9,9 @@ jobs:
99
lint:
1010
uses: ./.github/workflows/lint.yml
1111

12-
release-build:
12+
build:
1313
runs-on: ubuntu-latest
14+
environment: release
1415
needs:
1516
- run-tests
1617
- lint
@@ -20,23 +21,24 @@ jobs:
2021

2122
- uses: actions/setup-python@v5
2223
with:
23-
python-version: "3.x"
24+
# Using with <3.13 since cgi was removed in 3.13
25+
python-version: "3.11"
2426

2527
- name: Build distribution 📦
2628
run: |
27-
docker compose -f docker-compose.ci.yml up -d --build
29+
pip install -r requirements.txt
2830
make package
2931
3032
- name: upload dists
3133
uses: actions/upload-artifact@v4
3234
with:
33-
name: release-dists
35+
name: python-package-distributions
3436
path: dist/
3537

3638
publish-to-pypi:
3739
name: >-
38-
Publish Python 🐍 distribution 📦 to PyPI
39-
if: startsWith(github.ref, 'refs/tags/') && github.actor == 'trangpham'
40+
Publish to PyPI
41+
if: github.actor == 'trangpham'
4042
needs:
4143
- build
4244
runs-on: ubuntu-latest
@@ -57,11 +59,11 @@ jobs:
5759

5860
github-release:
5961
name: >-
60-
Sign the Python 🐍 distribution 📦 with Sigstore
61-
and upload them to GitHub Release
62+
Upload to GitHub Release
6263
needs:
6364
- publish-to-pypi
6465
runs-on: ubuntu-latest
66+
environment: release
6567

6668
permissions:
6769
contents: write # IMPORTANT: mandatory for making GitHub Releases

.github/workflows/test.yml

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,23 @@ jobs:
4444
options: --health-cmd="curl http://localhost:4566/health?reload" --health-interval=10s --health-timeout=5s --health-retries=3
4545
strategy:
4646
matrix:
47-
python-version: [3.8, 3.9, 3.10.0, 3.11]
48-
django-version: [3.2, 4.0.4]
47+
python-version: [3.8, 3.9, 3.10.0]
48+
django-version: [3.2, 4.2]
4949
include:
50-
# Version 4.0 of Django drops support for python 3.6 & 3.7
51-
- python-version: 3.7
52-
django-version: 3.2
50+
# Version 4.2 adds support for 3.11 & 3.12
51+
- python-version: 3.11
52+
django-version: 4.2
53+
- python-version: 3.12
54+
django-version: 4.2
55+
# Version 5.2 drops support for 3.8 & 3.9
56+
- python-version: 3.10.0
57+
django-version: 5.2
58+
- python-version: 3.11
59+
django-version: 5.2
60+
- python-version: 3.12
61+
django-version: 5.2
62+
- python-version: 3.13
63+
django-version: 5.2
5364
env:
5465
DJANGO_VERSION: ${{ matrix.django-version }}
5566
PYTHON_VERSION: ${{ matrix.python-version }}
@@ -63,21 +74,21 @@ jobs:
6374
sudo chown -R $USER:$USER ${{ github.workspace }}
6475
# required because actions/checkout@2 wants to delete the localstack folder
6576
- uses: actions/checkout@v2
66-
- name: Build Docker for Python 3.6
67-
if: ${{ matrix.python-version == 3.6 }}
68-
run: |
69-
export SELENIUM_VERSION=3.141.0
70-
docker compose -f docker-compose.ci.yml up -d --build
71-
# Note: Github Runners no longer supports docker-compose, use docker compose instead
72-
# see https://github.com/orgs/community/discussions/116610
77+
# - name: Build Docker for Python 3.6
78+
# if: ${{ matrix.python-version == 3.6 }}
79+
# run: |
80+
# export SELENIUM_VERSION=3.141.0
81+
# docker compose -f docker-compose.ci.yml up -d --build
82+
# Note: Github Runners no longer supports docker-compose, use docker compose instead
83+
# see https://github.com/orgs/community/discussions/116610
7384
- name: Build Docker for other Python versions
7485
if: ${{ matrix.python-version != 3.6 }}
7586
run: |
7687
export SELENIUM_VERSION=4.0.0a7
7788
docker compose -f docker-compose.ci.yml up -d --build
7889
- name: Attempt to connect to localstack and create bucket
7990
run: |
80-
curl -X GET http://localhost:4566/health
91+
curl -X GET http://localhost:4566/_localstack/health
8192
aws --endpoint-url http://localhost:4566 s3 mb s3://mybucket 2> /dev/null || true
8293
# Since docker-entrypoint-initaws.d can't be used to create the s3 bucket on CI
8394
- name: Integration Test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ db.sqlite3
3939
tmp/
4040

4141
.python-version
42+
volume/*

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@ t:
1515
test-integration:
1616
coverage run --source admin_confirm --branch -m pytest --ignore=admin_confirm/tests/unit
1717

18+
docker-build:
19+
docker-compose -f docker-compose.dev.yml build
20+
21+
docker-up:
22+
docker-compose -f docker-compose.dev.yml up -d
23+
1824
docker-exec:
1925
docker-compose -f docker-compose.dev.yml exec -T web ${COMMAND}
2026

27+
create-bucket:
28+
docker-compose -f docker-compose.dev.yml exec -T localstack awslocal s3 mb s3://mybucket
29+
2130
check-readme:
2231
python -m readme_renderer README.md -o /tmp/README.html
2332

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![PyPI](https://img.shields.io/pypi/v/django-admin-confirm?color=blue)](https://pypi.org/project/django-admin-confirm/) ![Tests Status](https://github.com/TrangPham/django-admin-confirm/actions/workflows/.github/workflows/test.yml/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/TrangPham/django-admin-confirm/badge.svg)](https://coveralls.io/github/TrangPham/django-admin-confirm)
44
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/django-admin-confirm) ![PyPI - Django Version](https://img.shields.io/pypi/djversions/django-admin-confirm)
5-
![PyPI - License](https://img.shields.io/pypi/l/django_admin_confirm) ![Status](https://img.shields.io/badge/status-alpha-yellow)
5+
![PyPI - License](https://img.shields.io/pypi/l/django_admin_confirm)
66

77
AdminConfirmMixin is a mixin for ModelAdmin to add confirmations to change, add and actions.
88

admin_confirm/tests/helpers.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import socket
22

33
from django.core.cache import cache
4-
from django.test import TestCase, RequestFactory
4+
from django.test import TestCase, RequestFactory, LiveServerTestCase
55
from django.contrib.auth.models import User
6-
from django.test import LiveServerTestCase
76
from tests.test_project.settings import SELENIUM_HOST
87

98
from selenium import webdriver
@@ -39,9 +38,7 @@ def _assertManyToManyFormHtml(self, rendered_content, options, selected_ids):
3938
# ManyToManyField should be embedded
4039
self.assertIn("related-widget-wrapper", rendered_content)
4140

42-
def _assertSubmitHtml(
43-
self, rendered_content, save_action="_save", multipart_form=False
44-
):
41+
def _assertSubmitHtml(self, rendered_content, save_action="_save", multipart_form=False):
4542
# Submit should conserve the save action
4643
self.assertIn(
4744
f'<input type="submit" value="Yes, I’m sure" name="{save_action}">',
@@ -79,7 +76,7 @@ def setUpClass(cls):
7976
cls.host = socket.gethostbyname(socket.gethostname())
8077
cls.selenium = webdriver.Remote(
8178
command_executor=f"http://{SELENIUM_HOST}:4444/wd/hub",
82-
desired_capabilities=DesiredCapabilities.FIREFOX,
79+
options=webdriver.FirefoxOptions(),
8380
)
8481
super().setUpClass()
8582

admin_confirm/tests/integration/test_with_s3_storage.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
on ModelAdmin that utilize caches
44
and S3 as a storage backend
55
"""
6+
67
import os
78

89
import pytest
910
import pkg_resources
1011
import localstack_client.session
12+
import django
1113

1214
from importlib import reload
1315
from selenium.webdriver.remote.file_detector import LocalFileDetector
@@ -23,6 +25,9 @@
2325
from admin_confirm.constants import CONFIRM_CHANGE
2426

2527

28+
DJANGO_VERSION = django.__version__
29+
30+
2631
class ConfirmWithS3StorageTests(AdminConfirmIntegrationTestCase):
2732
def setUp(self):
2833
self.selenium.file_detector = LocalFileDetector()
@@ -44,10 +49,19 @@ def tearDown(self):
4449
def test_s3_is_being_used(self):
4550
self.assertTrue(settings.USE_S3)
4651
self.assertIsNotNone(settings.AWS_ACCESS_KEY_ID)
47-
self.assertEqual(
48-
settings.DEFAULT_FILE_STORAGE,
49-
"tests.storage_backends.PublicMediaStorage",
50-
)
52+
53+
if DJANGO_VERSION >= "4.2":
54+
# Available since Django 4.2
55+
self.assertEqual(
56+
settings.STORAGES["default"]["BACKEND"],
57+
"tests.storage_backends.PublicMediaStorage",
58+
)
59+
else:
60+
# Deprecated in Django 5.1
61+
self.assertEqual(
62+
settings.DEFAULT_FILE_STORAGE,
63+
"tests.storage_backends.PublicMediaStorage",
64+
)
5165

5266
def test_should_save_file_additions(self):
5367
selenium_version = pkg_resources.get_distribution("selenium").parsed_version
@@ -56,23 +70,17 @@ def test_should_save_file_additions(self):
5670
"Known issue `https://github.com/SeleniumHQ/selenium/issues/8762` with this selenium version."
5771
)
5872

59-
item = Item.objects.create(
60-
name="item", price=1, currency=Item.VALID_CURRENCIES[0][0]
61-
)
73+
item = Item.objects.create(name="item", price=1, currency=Item.VALID_CURRENCIES[0][0])
6274

63-
self.selenium.get(
64-
self.live_server_url + f"/admin/market/item/{item.id}/change/"
65-
)
75+
self.selenium.get(self.live_server_url + f"/admin/market/item/{item.id}/change/")
6676
self.assertIn(CONFIRM_CHANGE, self.selenium.page_source)
6777

6878
# Make a change to trigger confirmation page
6979
price = self.selenium.find_element(By.NAME, "price")
7080
price.send_keys(2)
7181

7282
# Upload a new file
73-
self.selenium.find_element(By.ID, "id_file").send_keys(
74-
os.getcwd() + "/screenshot.png"
75-
)
83+
self.selenium.find_element(By.ID, "id_file").send_keys(os.getcwd() + "/screenshot.png")
7684

7785
self.selenium.find_element(By.NAME, "_continue").click()
7886

@@ -110,19 +118,15 @@ def test_should_save_file_changes(self):
110118
name="item", price=1, currency=Item.VALID_CURRENCIES[0][0], file=file
111119
)
112120

113-
self.selenium.get(
114-
self.live_server_url + f"/admin/market/item/{item.id}/change/"
115-
)
121+
self.selenium.get(self.live_server_url + f"/admin/market/item/{item.id}/change/")
116122
self.assertIn(CONFIRM_CHANGE, self.selenium.page_source)
117123

118124
# Make a change to trigger confirmation page
119125
price = self.selenium.find_element(By.NAME, "price")
120126
price.send_keys(2)
121127

122128
# Upload a new file
123-
self.selenium.find_element(By.ID, "id_file").send_keys(
124-
os.getcwd() + "/screenshot.png"
125-
)
129+
self.selenium.find_element(By.ID, "id_file").send_keys(os.getcwd() + "/screenshot.png")
126130

127131
self.selenium.find_element(By.NAME, "_continue").click()
128132

@@ -143,9 +147,7 @@ def test_should_save_file_changes(self):
143147
objects = [obj for obj in self.bucket.objects.all()]
144148
self.assertEqual(len(objects), 2)
145149
get_last_modified = lambda obj: int(obj.last_modified.strftime("%s"))
146-
objects_by_last_modified = [
147-
obj for obj in sorted(objects, key=get_last_modified)
148-
]
150+
objects_by_last_modified = [obj for obj in sorted(objects, key=get_last_modified)]
149151
self.assertRegex(objects_by_last_modified[-1].key, r"screenshot.*\.png$")
150152
self.assertRegex(objects_by_last_modified[0].key, r"old_file.*\.jpg$")
151153

@@ -159,9 +161,7 @@ def test_should_remove_file_if_clear_selected(self):
159161
name="item", price=1, currency=Item.VALID_CURRENCIES[0][0], file=file
160162
)
161163

162-
self.selenium.get(
163-
self.live_server_url + f"/admin/market/item/{item.id}/change/"
164-
)
164+
self.selenium.get(self.live_server_url + f"/admin/market/item/{item.id}/change/")
165165
self.assertIn(CONFIRM_CHANGE, self.selenium.page_source)
166166

167167
# Make a change to trigger confirmation page
@@ -171,9 +171,9 @@ def test_should_remove_file_if_clear_selected(self):
171171
# Choose to clear the existing file
172172
self.selenium.find_element(By.ID, "file-clear_id").click()
173173
self.assertTrue(
174-
self.selenium.find_element(
175-
By.XPATH, ".//*[@id='file-clear_id']"
176-
).get_attribute("checked")
174+
self.selenium.find_element(By.XPATH, ".//*[@id='file-clear_id']").get_attribute(
175+
"checked"
176+
)
177177
)
178178

179179
self.selenium.find_element(By.NAME, "_continue").click()

0 commit comments

Comments
 (0)