Skip to content

Commit 4569028

Browse files
authored
Stabilize CI runtime dependencies (#298)
1 parent dee841f commit 4569028

5 files changed

Lines changed: 88 additions & 28 deletions

File tree

.github/workflows/CDA-testing.yml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,36 @@ on:
99

1010
jobs:
1111
integration-tests:
12+
name: integration-tests (Python ${{ matrix.python-version }}, CDA ${{ matrix.cda.name }},
13+
schema ${{ matrix.schema.name }})
1214
runs-on: ubuntu-latest
15+
timeout-minutes: 60
1316

1417
strategy:
1518
fail-fast: false
19+
max-parallel: 6
1620
matrix:
1721
python-version: ['3.9', '3.13']
22+
# Keep the release pins in sync with the environments (see CONTRIBUTING.md).
23+
cda:
24+
- name: latest
25+
image: ghcr.io/usace/cwms-data-api:develop-nightly
26+
- name: production
27+
image: ghcr.io/usace/cwms-data-api:2026.05.12-i
28+
- name: test
29+
image: ghcr.io/usace/cwms-data-api:2026.08.31-testd
30+
schema:
31+
- name: latest
32+
tag: latest-dev
33+
- name: production
34+
tag: '26.02.17'
35+
- name: test
36+
tag: 26.07.16-RC02
37+
38+
env:
39+
CWMS_DATA_API_IMAGE: ${{ matrix.cda.image }}
40+
CWMS_DATABASE_IMAGE: ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/database-ready-ora-23.5:${{ matrix.schema.tag }}
41+
CWMS_SCHEMA_INSTALLER_IMAGE: ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/schema_installer:${{ matrix.schema.tag }}
1842

1943
steps:
2044
- uses: actions/checkout@v7
@@ -29,9 +53,10 @@ jobs:
2953
- name: Set up backend
3054
run: |
3155
docker compose pull
32-
docker compose up -d
56+
docker compose up -d --wait --wait-timeout 2400
3357
3458
- name: Set Up Python
59+
id: setup-python
3560
uses: actions/setup-python@v6
3661
with:
3762
python-version: ${{ matrix.python-version }}
@@ -50,8 +75,8 @@ jobs:
5075
id: cache-poetry-venv
5176
with:
5277
path: .venv
53-
key: ${{ runner.os }}-py${{ matrix.python-version }}-poetry-${{ hashFiles('poetry.lock')
54-
}}
78+
key: ${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-poetry-${{
79+
hashFiles('poetry.lock') }}
5580

5681
# Install dependencies only if cache is missed
5782
- name: Install dependencies
@@ -78,3 +103,11 @@ jobs:
78103
file: ./code-coverage-results.md
79104
vars: |-
80105
empty: empty
106+
107+
- name: Show backend logs on failure
108+
if: failure()
109+
run: docker compose logs --no-color --tail 200
110+
111+
- name: Stop test backend
112+
if: always()
113+
run: docker compose down --volumes

.github/workflows/testing.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
- uses: actions/checkout@v7
1313

1414
- name: Set Up Python
15+
id: setup-python
1516
uses: actions/setup-python@v6
1617
with:
1718
python-version: '3.13'
@@ -25,7 +26,8 @@ jobs:
2526
uses: actions/cache@v6
2627
with:
2728
path: ./.venv
28-
key: venv-${{ hashFiles('poetry.lock') }}
29+
key: ${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-venv-${{
30+
hashFiles('poetry.lock') }}
2931

3032
- name: Install Dependencies
3133
run: poetry install

CONTRIBUTING.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,46 @@ passed, bearer token auth takes precedence.
7979
8080
> **Note:** If you are running other instances of CDA or Oracle on your machine, they may use different ports. Always verify which ports are in use and update your configuration files accordingly to avoid conflicts.
8181
82+
#### Selecting CDA and Database Versions
83+
84+
Local Compose defaults to CDA `develop-nightly` and database/schema-installer
85+
`latest-dev`. Override the image references in a local, uncommitted `.env`
86+
file when reproducing a particular environment, for example:
87+
88+
```dotenv
89+
CWMS_DATA_API_IMAGE=ghcr.io/usace/cwms-data-api:2026.05.12-i
90+
CWMS_DATABASE_IMAGE=ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/database-ready-ora-23.5:26.02.17
91+
CWMS_SCHEMA_INSTALLER_IMAGE=ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/schema_installer:26.02.17
92+
```
93+
94+
Keep the database and schema-installer tags together. Use a separate Compose
95+
project for each database version, so the test data and containers are isolated:
96+
97+
```sh
98+
docker compose -p cwms-python-release pull
99+
docker compose -p cwms-python-release up -d --wait --wait-timeout 2400
100+
```
101+
102+
Use the same project name for subsequent `ps`, `logs`, and `down` commands.
103+
Stop the previous stack before starting another one using the same host ports.
104+
105+
The integration workflow in `.github/workflows/CDA-testing.yml` tests every
106+
combination of three CDA images and three database versions on Python 3.9
107+
and 3.13 (18 jobs):
108+
109+
| Lane | CDA tag | Database and schema-installer tag |
110+
| --- | --- | --- |
111+
| latest | `develop-nightly` | `latest-dev` |
112+
| production | `2026.05.12-i` | `26.02.17` |
113+
| test | `2026.08.31-testd` | `26.07.16-RC02` |
114+
115+
These release pins are maintained in the workflow; update them when the
116+
target environments change. CDA and database are independent matrix axes,
117+
so testing includes mixed versions, not only the three same-lane pairs.
118+
Each job starts a disposable local stack, waits for backend health, and
119+
uses the hashed test keys seeded by `compose_files/sql/users.sql`. CI never
120+
runs these destructive integration tests against the deployed environments.
121+
82122
3. **Run Tests Against CDA**
83123
Once the services are running, execute the tests:
84124
```sh

docker-compose.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ volumes:
33
auth_data:
44
services:
55
db:
6-
image: ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/database-ready-ora-23.5:latest-dev
6+
image: ${CWMS_DATABASE_IMAGE:-ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/database-ready-ora-23.5:latest-dev}
77
environment:
88
#- ORACLE_DATABASE=FREEPDB1
99
- ORACLE_PASSWORD=badSYSpassword
1010
- CWMS_PASSWORD=simplecwmspasswD1
1111
- OFFICE_ID=HQ
12-
- OFFICE_EROC=s0
12+
- OFFICE_EROC=q0
1313
ports: ["1526:1521"]
1414
healthcheck:
1515
test: ["CMD", "tnsping", "FREEPDB1"]
@@ -18,7 +18,7 @@ services:
1818
retries: 50
1919
start_period: 40m
2020
db_webuser_permissions:
21-
image: ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/schema_installer:latest-dev
21+
image: ${CWMS_SCHEMA_INSTALLER_IMAGE:-ghcr.io/hydrologicengineeringcenter/cwms-database/cwms/schema_installer:latest-dev}
2222
restart: "no"
2323
environment:
2424
- DB_HOST_PORT=db:1521
@@ -27,7 +27,7 @@ services:
2727
- SYS_PASSWORD=badSYSpassword
2828
# set to HQ/q0 for any national system work
2929
- OFFICE_ID=HQ
30-
- OFFICE_EROC=s0
30+
- OFFICE_EROC=q0
3131
- INSTALLONCE=1
3232
- QUIET=1
3333
command: >
@@ -52,15 +52,15 @@ services:
5252
condition: service_completed_successfully
5353
traefik:
5454
condition: service_healthy
55-
image: ${CWMS_DATA_API_IMAGE:-ghcr.io/usace/cwms-data-api:latest}
55+
image: ${CWMS_DATA_API_IMAGE:-ghcr.io/usace/cwms-data-api:develop-nightly}
5656
restart: unless-stopped
5757
volumes:
5858
- ./compose_files/pki/certs:/conf/
5959
- ./compose_files/tomcat/logging.properties:/usr/local/tomcat/conf/logging.properties:ro
6060
environment:
6161
- CDA_JDBC_DRIVER=oracle.jdbc.driver.OracleDriver
6262
- CDA_JDBC_URL=jdbc:oracle:thin:@db/FREEPDB1
63-
- CDA_JDBC_USERNAME=s0webtest
63+
- CDA_JDBC_USERNAME=q0webtest
6464
- CDA_JDBC_PASSWORD=simplecwmspasswD1
6565
- CDA_POOL_INIT_SIZE=5
6666
- CDA_POOL_MAX_ACTIVE=10
@@ -140,4 +140,3 @@ services:
140140
- "traefik.enable=true"
141141
- "traefik.http.routers.traefik.rule=PathPrefix(`/traefik`)"
142142
- "traefik.http.routers.traefik.service=api@internal"
143-

tests/cda/timeseries/timeseries_groups_test.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -155,24 +155,10 @@ def test_update_timeseries_groups():
155155

156156
def test_delete_timeseries_group():
157157

158-
# update with no timeseries in the group first
159-
df = pd.DataFrame(columns=["timeseries-id", "office-id", "alias"])
160-
161-
json_dict = tg.timeseries_group_df_to_json(
162-
data=df,
158+
# delete the group
159+
tg.delete_timeseries_group(
163160
group_id=TEST_GROUP_ID,
164-
group_office_id=TEST_OFFICE,
165-
category_office_id=TEST_OFFICE,
166161
category_id=TEST_CATEGORY_ID,
167-
)
168-
tg.update_timeseries_groups(
169-
group_id=TEST_GROUP_ID,
170162
office_id=TEST_OFFICE,
171-
replace_assigned_ts=True,
172-
data=json_dict,
173-
)
174-
175-
# delete the group
176-
tg.delete_timeseries_group(
177-
group_id=TEST_GROUP_ID, category_id=TEST_CATEGORY_ID, office_id=TEST_OFFICE
163+
cascade_delete=True,
178164
)

0 commit comments

Comments
 (0)