Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
4b35392
Fix SQLite schema-name lookup in TableValidator and dataDictionary
bjfultn May 20, 2026
b2e2b78
Add CI: GitHub Actions, SQLite test fixture, ruff lint
bjfultn May 20, 2026
1436c9f
CI: install nexsciTAP and ADQL with --no-deps to work around spatial_…
bjfultn May 20, 2026
0031821
CI: add sqlparse, astropy, bs4, xmltodict to test deps
bjfultn May 20, 2026
669983f
Add security regression tests + pyNEID compat scaffolding
bjfultn May 20, 2026
ceafae0
Merge pull request #20 from Caltech-IPAC/ci/infrastructure-and-fixture
bjfultn May 20, 2026
a0eb278
Merge pull request #21 from Caltech-IPAC/ci/security-and-pyneid-tests
bjfultn May 20, 2026
7e865c7
Merge main into develop: catch up v3.0.1 hotfix
bjfultn Jun 2, 2026
2ac7dc8
Merge pull request #23 from Caltech-IPAC/chore/main-into-develop-v3.0.1
bjfultn Jun 2, 2026
2565a6d
Fix malformed HTTP responses from /capabilities and /availability
bjfultn Sep 10, 2026
4a12ff9
Unblock CI: strip trailing whitespace and pin ruff
bjfultn Sep 10, 2026
ca7a755
Cover the fresh-deployment case deterministically
bjfultn Sep 10, 2026
a0955e3
Spell out the CRLF terminator with end='\r\n'
bjfultn Sep 10, 2026
202f4d1
Serve the VOSI documents as application/xml
bjfultn Sep 11, 2026
319effc
test: make the fixture able to host an async job
Sep 22, 2026
a59eb90
fix: detach async jobs by forking, not by killing the web server
Sep 22, 2026
6663346
fix: stop async ABORT and bad phases from running the job
Sep 22, 2026
e1656ca
Use tap_schema_file only for SQLite
bjfultn Oct 6, 2026
f4ebf35
Add compat mode's config side: COMPAT names and the 1.x reader
bjfultn Oct 6, 2026
e95ffc6
compat: nea-vosi-headers, and a 1.x-config test server
bjfultn Oct 6, 2026
19a25ed
compat: nea-errors (VOTable error documents, 400 for unlisted tables)
bjfultn Oct 6, 2026
26e3bc8
compat: nea-votable (application/xml, no non-char FIELD descriptions)
bjfultn Oct 6, 2026
45cc471
compat: nea-uws (executionDuration, destruction without Z, NEA conten…
bjfultn Oct 6, 2026
0c0efb5
compat: nea-tables (NEA's /tables writer, kept verbatim from bbc1108)
bjfultn Oct 6, 2026
fc516b2
compat: daily deprecation warning, MIGRATING.md, version 3.1.0
bjfultn Oct 6, 2026
503ca96
compat: nea-uws job-run 303 framing matches NEA
bjfultn Oct 6, 2026
5f03ef4
compat: accept executionDuration URL key; tolerant status read; COMPA…
bjfultn Oct 6, 2026
cd6eb53
docs: MIGRATING.md matches compat behavior; tablevalidator comment
bjfultn Oct 6, 2026
f6a1bd1
test: use generic host and cookie names in compat tests
bjfultn Oct 6, 2026
e58b9b1
Merge pull request #30 from Caltech-IPAC/nea/compat
bjfultn Oct 6, 2026
f102d9b
Merge pull request #28 from Caltech-IPAC/fix/async-detach-without-kil…
bjfultn Oct 6, 2026
3b874fa
Merge develop: VOSI headers come from compat.vosi_head
bjfultn Oct 6, 2026
4ace738
Merge pull request #27 from Caltech-IPAC/fix/vosi-crlf-headers
bjfultn Oct 6, 2026
8cf8f41
Declare runtime dependencies in setup.py
bjfultn Oct 6, 2026
86fcfeb
Merge pull request #31 from Caltech-IPAC/fix/declare-runtime-deps
bjfultn Oct 6, 2026
426c999
Keep every 1.x [webserver] key when translating to 3.x
bjfultn Oct 6, 2026
bc125fd
Merge pull request #32 from Caltech-IPAC/fix/compat-legacy-propfilter
bjfultn Oct 6, 2026
3fd38f4
UWS: delete jobs, 404 unknown jobs, executionDuration, consistent values
bjfultn Oct 6, 2026
614123e
Merge pull request #33 from Caltech-IPAC/fix/uws-conformance
bjfultn Oct 21, 2026
31197ab
Size Oracle DATE columns like DATETIME in IPAC-table output
bjfultn Oct 27, 2026
f7372a6
Port the 3.0.2 proprietary-access fixes to develop
bjfultn Oct 27, 2026
27ccc3a
CI: run the test matrix on ubuntu-24.04
bjfultn Oct 27, 2026
4034abe
Merge pull request #36 from Caltech-IPAC/ci/pin-ubuntu-24.04
bjfultn Oct 27, 2026
be4bda1
Merge branch 'develop' into fix/oracle-date-width
bjfultn Oct 27, 2026
ea1720f
Merge branch 'develop' into fix/port-3.0.2-security
bjfultn Oct 27, 2026
e8b8b72
Merge pull request #34 from Caltech-IPAC/fix/oracle-date-width
bjfultn Oct 27, 2026
f8a0387
Merge pull request #35 from Caltech-IPAC/fix/port-3.0.2-security
bjfultn Oct 27, 2026
5cfb6af
Merge branch 'main' into release/v3.1.0
bjfultn Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: CI

on:
pull_request:
push:
branches: [main, develop]

jobs:
test:
name: test (py${{ matrix.python-version }})
# Pinned: ubuntu-latest moved to 26.04, which has no Python 3.9 build for
# actions/setup-python, so the py3.9 job failed before running any tests.
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install package and test deps
# `spatial_index` on PyPI has no wheels for Python 3.9+ and no
# source distribution, so `pip install .` cannot resolve it on the
# modern matrix. Install nexsciTAP with --no-deps and rely on the
# test fixture's spatial_index stub (tests/fixtures/stubs/) on
# PYTHONPATH for the constants TAP imports. configobj is the only
# actually-needed runtime dep and is in requirements-test.txt.
# ADQL is installed with --no-deps for the same reason.
run: |
pip install --upgrade pip
pip install -r requirements-test.txt
pip install --no-deps "ADQL==1.0.6"
pip install --no-deps .

- name: Lint with ruff
run: ruff check .

- name: Run tests
run: pytest tests/ -v

wheel-platforms:
name: wheel build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Build wheel
run: |
pip install --upgrade pip build
python -m build --wheel

- name: Verify wheel artifact
# See test job for spatial_index PyPI situation. We can't install
# the wheel's full deps on modern Python; just confirm the wheel
# was built and includes the C extension.
run: |
ls dist/
python -c "
import zipfile, glob
wheel = glob.glob('dist/*.whl')[0]
with zipfile.ZipFile(wheel) as z:
names = z.namelist()
assert any('writerecs' in n and n.endswith('.so') for n in names), \
f'C extension missing from wheel: {names}'
print(f'wheel OK: {wheel}')
print('contains C extension')
"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
*.[oa]
*~
*.so
/Sphinx/_build
/TAP/__pycache__
/TAP/writerecs.cpython-36m-darwin.so
/build
/dist
/final_dist
/final_wheel
/nexsciTAP.egg-info
__pycache__/
.pytest_cache/

# Workflow artifacts (Claude Code planning/spec docs, not project documentation)
/docs/superpowers/
75 changes: 0 additions & 75 deletions HOTFIX-3.0.2.md

This file was deleted.

2 changes: 0 additions & 2 deletions MANIFEST.in

This file was deleted.

74 changes: 74 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Migrating from the 1.x TAP.conf layout and NEA compatibility mode

nexsciTAP 3.1 runs deployments that still use the 1.x `TAP.conf` layout
(`[webserver]`, a section named by `DBMS=`, top-level `ADQL_*` keys). A 1.x
config is translated to the 3.x layout when it's read, and it turns on
**compatibility mode**: the responses that deployment sent under nexsciTAP
1.2. Compatibility mode is temporary. While it's on, the service writes one
line a day to stderr (the web server's error log):

nexsciTAP: compatibility mode active (...); see MIGRATING.md

## Compatibility behaviors

| Name | With it (1.2 behavior) | Without it (3.x behavior) |
|---|---|---|
| `nea-vosi-headers` | `/availability` and `/capabilities` also send `Connection: close`, and end with an extra CRLF | status line and `Content-type` only |
| `nea-errors` | errors are VOTable documents; a table not in TAP_SCHEMA returns 400 | plain text; 403 |
| `nea-tables` | `/tables` uses VODataService `<flag>` elements | per-column `<principal>`, `<indexed>`, `<std>`, `<column_index>`, `<arraysize>` |
| `nea-votable` | VOTable results are `application/xml`, non-char FIELDs carry no DESCRIPTION (units are still written) | `text/xml`, with descriptions on every FIELD |
| `nea-uws` | job documents are `application/xml`, no `Z` on `destruction`; the 303 that starts a job (`PHASE=RUN`) carries no `Content-Type`, `Content-Length` or `Connection` lines, because the response ends when the CGI exits; `/async/<id>/executionDuration` (camelCase) is accepted as well as `/executionduration`; job URLs join `HTTP_URL` and `CGI_PGM` with `/` as written, so `CGI_PGM=/TAP` gives `//TAP` | `text/xml`, `Z`; the 303 carries `Content-Type: text/plain`, `Content-Length` and `Connection: close`; only `/executionduration` is a valid key; job URLs have one `/` between `HTTP_URL` and `CGI_PGM` |

## Moving to the 3.x layout

1. Translate the config, keeping every behavior: in `[WEB]`, list them all.

| 1.x | 3.x |
|---|---|
| `[webserver]` `TAP_WORKDIR`, `TAP_WORKURL`, `HTTP_URL`, `HTTP_PORT`, `CGI_PGM`, `ArraySize`, `INFOMSG` | `[WEB]`, same keys |
| `[webserver]` `DBMS` | `[DBMS]` `DBMS` |
| the `[oracle]` / `[sqlite3]` section's keys | `[DBMS]`, same keys |
| `[webserver]` `COOKIENAME`, `RACOL`, `DECCOL` | `[DBMS]`, same keys |
| `ADQL_MODE`, `ADQL_LEVEL`, `ADQL_XCOL`, `ADQL_YCOL`, `ADQL_ZCOL`, `ADQL_COLNAME`, `ADQL_ENCODING` | `[SPTIND]` `MODE`, `LEVEL`, `XCOL`, `YCOL`, `ZCOL`, `COLNAME`, `ENCODING` |

```ini
[WEB]
COMPAT = nea-vosi-headers, nea-errors, nea-tables, nea-votable, nea-uws
```
Responses don't change.

2. Remove names from `COMPAT` one at a time, each as an announced change for
that service's users.
3. When `COMPAT` is empty, remove the key.

## Known differences from 1.2

Compatibility mode reproduces 1.2's responses, with these exceptions:

- Errors raised before `TAP.conf` is read (a missing or broken `TAP.conf`, a
malformed request path) use the 3.x error format, since the mode isn't known
yet.
- The async job document escapes quotes in the query text as `&#x27;`; it
parses to the same XML.
- Both modes write the job document's duration as `executionDuration` (the
UWS name) and read either spelling, so jobs written by an earlier release
or under the other mode read correctly.
- Both modes follow UWS where 1.2 did not: a job can be deleted
(`POST ACTION=DELETE` or HTTP `DELETE`, answered with 303 to the job list),
an unknown job id is 404, `GET` on the job list returns an empty
`<uws:jobs>` instead of creating a job, and an unset job value (such as
`/destruction` before the job runs) is empty text instead of `None`.

`COMPAT` is read only from `[WEB]`; placing it in any other section, including
a 1.x `[webserver]`, is a configuration error.

## Release plan

- **3.1.0**: compatibility mode, the 1.x reader, this guide. The default
job document now spells the duration `executionDuration`, as UWS
requires, which retires that part of `nea-uws`.
- **3.x**: where the shared behavior is to change (for example VOTable
errors, which IVOA standards require), the release notes say so before
any default changes.
- **4.0.0**: compatibility mode, the `COMPAT` key and the 1.x reader are
removed; a 1.x `TAP.conf` then fails at startup with a pointer here.
2 changes: 1 addition & 1 deletion Sphinx/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
author = 'John Good'

# The full version, including alpha/beta/rc tags
release = '3.0.2'
release = '3.1.0'


# -- General configuration ---------------------------------------------------
Expand Down
Loading
Loading