crossref-matcher 1.3.1__tar.gz → 1.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {crossref_matcher-1.3.1/crossref_matcher.egg-info → crossref_matcher-1.3.2}/PKG-INFO +1 -1
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/README.md +93 -0
- crossref_matcher-1.3.2/crossref_matcher/indexes/ror_organizations/opensearch_utils.py +44 -0
- crossref_matcher-1.3.2/crossref_matcher/resources/VERSION.txt +1 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2/crossref_matcher.egg-info}/PKG-INFO +1 -1
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher.egg-info/SOURCES.txt +1 -1
- crossref_matcher-1.3.1/crossref_matcher/indexes/ror_organizations/ror_opensearch_update_dag.py +0 -124
- crossref_matcher-1.3.1/crossref_matcher/resources/VERSION.txt +0 -1
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/LICENSE +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/MANIFEST.in +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/MatchTask.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/app.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/all_links.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/api_routes.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/dataset_ingest.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/evaluation.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/google_sheets_connector.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/ror_utils.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/schemas.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/sparse_metrics_verification/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/sparse_metrics_verification/verify_sparse_metrics.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/indexes/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/indexes/preprint_matching/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/indexes/preprint_matching/indexer_service.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/indexes/ror_organizations/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/indexes/ror_organizations/create_index.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/indexes/ror_organizations/index_data.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/indexes/ror_organizations/ror_zenodo_api.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/matching/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/matching/http_utils.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/matching/run_strategy_on_dataset.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/matching/schemas.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/matching/search.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/matching/utils.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/affiliation/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/common_ror_endings/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/common_ror_endings/common_ror_endings.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/countries/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/countries/china_placenames.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/countries/countries.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/countries/countries2.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/datasets/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ensemble_ml/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ensemble_ml/data_counters0.pkl +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ensemble_ml/eval/events.out.tfevents.1690572611.knopfler.local +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ensemble_ml/model.opt_slots0.npy.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ensemble_ml/model.pkl.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ensemble_ml/model.weights.npy.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ensemble_ml/train/events.out.tfevents.1690572611.knopfler.local +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ml/data_counters0.pkl +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ml/eval/events.out.tfevents.1690302892.knopfler.local +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ml/model.opt_slots0.npy.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ml/model.pkl.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ml/model.weights.npy.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/preprint_ml/train/events.out.tfevents.1690302891.knopfler.local +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/reference_nn_unstructured/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/reference_nn_unstructured/data_counters0.pkl +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/reference_nn_unstructured/eval/events.out.tfevents.1681511550.knopfler.local +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/reference_nn_unstructured/model.opt_slots0.npy.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/reference_nn_unstructured/model.pkl.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/reference_nn_unstructured/model.weights.npy.gz +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/reference_nn_unstructured/train/events.out.tfevents.1681511550.knopfler.local +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/plugins.json +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/run_plugin_test.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/es_utils.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/matching.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/multi_search/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/multi_search/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/single_search/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/single_search/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/affiliation/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/common.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/funder/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/funder/funder_name_to_ror_search/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/funder/funder_name_to_ror_search/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/funder/funder_name_to_ror_search/version.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/healthcheck/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/healthcheck/healthcheck/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/healthcheck/healthcheck/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_avg/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_avg/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_cascade/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_cascade/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_ml/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_ml/get_train_data.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_ml/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_ml/train.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/ensemble_ml/utils.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/preprint_ml/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/preprint_ml/get_train_data.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/preprint_ml/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/preprint_ml/train.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/preprint_ml/utils.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/sbmv/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/sbmv/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/sbmv_es/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/sbmv_es/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/sbmv_rels/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/sbmv_rels/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/cs_combined/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/cs_combined/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/nn_unstructured/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/nn_unstructured/get_train_data.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/nn_unstructured/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/nn_unstructured/train.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/nn_unstructured/utils.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/parsed_doi/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/parsed_doi/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/parsed_isbn/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/parsed_isbn/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/sbmv/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/sbmv/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/sbmv_orig/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/sbmv_orig/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/sbmv_unstructured/__init__.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/sbmv_unstructured/strategy.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/versioning.py +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher.egg-info/dependency_links.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher.egg-info/entry_points.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher.egg-info/requires.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher.egg-info/top_level.txt +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/setup.cfg +0 -0
- {crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/setup.py +0 -0
|
@@ -185,3 +185,96 @@ Requirements are defined in `setup.py`. Requirements files with exact versions c
|
|
|
185
185
|
* To update `requirements.txt` file: `pip-compile setup.py --extra strategies-core`
|
|
186
186
|
|
|
187
187
|
* To update `requirements-tests.txt` file: `pip-compile setup.py --extra strategies-core --extra evaluation --extra test -o requirements-tests.txt`
|
|
188
|
+
|
|
189
|
+
## Branching and deployment
|
|
190
|
+
|
|
191
|
+
CI (see [.gitlab-ci.yml](.gitlab-ci.yml)) deploys from two long-lived branches:
|
|
192
|
+
|
|
193
|
+
| Branch / trigger | Deploys to | Jobs |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
| `dev` | **Research** environment | ECS deploy (`marple-research`), Airflow DAG data sync to `s3://airflow.crossref.org` (research-only bucket), `X.Y.Z-dev.N` prerelease tags |
|
|
196
|
+
| `main` | **Staging** environment | ECS deploy (`marple-staging`), GitLab-registry image for the integration project, release tags via semantic-release |
|
|
197
|
+
| Stable `vX.Y.Z` tags | PyPI | `crossref-matcher` published via OIDC trusted publishing (prerelease tags are not published) |
|
|
198
|
+
|
|
199
|
+
Both branches are protected. `main` is merged to via MR only; `dev`'s
|
|
200
|
+
protection must also allow Developers to push and merge directly
|
|
201
|
+
(**Settings → Repository → Protected branches → `dev` → Allowed to push
|
|
202
|
+
and merge**), since the workflow below pushes to it directly. Deploys are
|
|
203
|
+
automatic on push and are keyed on the commit SHA (`$CI_COMMIT_SHORT_SHA`),
|
|
204
|
+
independent of the semantic version.
|
|
205
|
+
|
|
206
|
+
### Feature workflow
|
|
207
|
+
|
|
208
|
+
1. **Branch off `main`** (not `dev`), so the feature can merge to `main`
|
|
209
|
+
cleanly regardless of what else is being tested on `dev`.
|
|
210
|
+
2. **To test on the research environment**, merge the feature into `dev` and
|
|
211
|
+
push (no MR needed — review happens at the `main` MR):
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
git checkout dev && git pull
|
|
215
|
+
git merge --no-ff my-feature
|
|
216
|
+
git push
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
3. **When validated, open an MR from the feature branch into `main`.**
|
|
220
|
+
Do not merge `dev` into `main` — `dev` may contain other unfinished work.
|
|
221
|
+
Use a [conventional commit](https://www.conventionalcommits.org/) message
|
|
222
|
+
(`feat:`/`fix:`) for the squash/merge commit; semantic-release derives the
|
|
223
|
+
release version from it.
|
|
224
|
+
4. **After the MR merges, merge `main` back into `dev`** to keep the branches
|
|
225
|
+
converged. This isn't strictly required — semantic-release's prerelease
|
|
226
|
+
branches skip the "behind the release branch" check — but without it,
|
|
227
|
+
`dev`'s next prerelease can recompute a version `main` already released,
|
|
228
|
+
or a confusing `vX.Y.Z-dev.N` alongside an already-shipped `vX.Y.Z`:
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
git checkout dev && git pull
|
|
232
|
+
git merge origin/main
|
|
233
|
+
git push
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Versioning
|
|
237
|
+
|
|
238
|
+
Releases are cut by semantic-release from conventional commit messages
|
|
239
|
+
(`fix:` → patch, `feat:` → minor, `BREAKING CHANGE` → major; other types cut
|
|
240
|
+
no release). On `dev`, release-worthy commits produce prerelease tags like
|
|
241
|
+
`v1.3.0-dev.1` (configured in [.releaserc.json](.releaserc.json)). Commits
|
|
242
|
+
without a `feat:`/`fix:` still deploy — only the tag is skipped, and
|
|
243
|
+
`VERSION.txt` keeps its `0.0.dev0` placeholder. To identify what is running
|
|
244
|
+
in an environment, use the commit SHA (the ECS image tag), not the version
|
|
245
|
+
string.
|
|
246
|
+
|
|
247
|
+
### Resetting a polluted `dev` back to `main`
|
|
248
|
+
|
|
249
|
+
`dev` is disposable: `main` never depends on its history. If `dev` has
|
|
250
|
+
accumulated abandoned experiments, reset it to `main` and re-merge only the
|
|
251
|
+
features still in flight:
|
|
252
|
+
|
|
253
|
+
1. Temporarily enable force-push for `dev` in GitLab
|
|
254
|
+
(**Settings → Repository → Protected branches → `dev` → Allowed to force push**).
|
|
255
|
+
2. Delete any `vX.Y.Z-dev.N` prerelease tags cut on the old `dev` — after the
|
|
256
|
+
reset their commits are unreachable from the branch, so semantic-release
|
|
257
|
+
won't see them and will try to recreate the same tag, failing every
|
|
258
|
+
subsequent release-worthy `dev` push until they're gone:
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
git tag -l 'v*-dev.*' | xargs -r git push origin --delete
|
|
262
|
+
git tag -l 'v*-dev.*' | xargs -r git tag -d
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
3. Reset and push:
|
|
266
|
+
|
|
267
|
+
```sh
|
|
268
|
+
git fetch origin
|
|
269
|
+
git checkout dev
|
|
270
|
+
git reset --hard origin/main
|
|
271
|
+
git push --force-with-lease origin dev
|
|
272
|
+
git merge --no-ff still-in-flight-feature # re-merge anything still being tested
|
|
273
|
+
git push
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
4. Disable force-push again.
|
|
277
|
+
|
|
278
|
+
The reset push re-deploys research and re-syncs the Airflow DAG data in
|
|
279
|
+
`s3://airflow.crossref.org` to the reset state (the sync uses `--delete`, so
|
|
280
|
+
files added by abandoned experiments are removed, not just left stale).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Shared OpenSearch client utilities for ROR index DAG tasks."""
|
|
2
|
+
|
|
3
|
+
import base64
|
|
4
|
+
import boto3
|
|
5
|
+
|
|
6
|
+
REGION = "us-east-1"
|
|
7
|
+
INDEX = "organization"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_secret(secret_name: str) -> str | bytes:
|
|
11
|
+
"""Retrieve a secret value from AWS Secrets Manager."""
|
|
12
|
+
session = boto3.session.Session()
|
|
13
|
+
client = session.client(service_name="secretsmanager", region_name=REGION)
|
|
14
|
+
|
|
15
|
+
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
|
|
16
|
+
if "SecretString" in get_secret_value_response:
|
|
17
|
+
return get_secret_value_response["SecretString"]
|
|
18
|
+
else:
|
|
19
|
+
return base64.b64decode(get_secret_value_response["SecretBinary"])
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_es_client(host: str | None = None):
|
|
23
|
+
"""Create an authenticated OpenSearch client using AWS credentials."""
|
|
24
|
+
from opensearchpy import (
|
|
25
|
+
OpenSearch,
|
|
26
|
+
RequestsHttpConnection,
|
|
27
|
+
AWSV4SignerAuth,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if host is None:
|
|
31
|
+
host = get_secret("es-host-matching")
|
|
32
|
+
|
|
33
|
+
credentials = boto3.Session().get_credentials()
|
|
34
|
+
auth = AWSV4SignerAuth(credentials, REGION, "es")
|
|
35
|
+
|
|
36
|
+
return OpenSearch(
|
|
37
|
+
hosts=[{"host": host, "port": 443}],
|
|
38
|
+
http_auth=auth,
|
|
39
|
+
use_ssl=True,
|
|
40
|
+
verify_certs=True,
|
|
41
|
+
connection_class=RequestsHttpConnection,
|
|
42
|
+
pool_maxsize=20,
|
|
43
|
+
timeout=120,
|
|
44
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.3.2
|
|
@@ -28,7 +28,7 @@ crossref_matcher/indexes/preprint_matching/indexer_service.py
|
|
|
28
28
|
crossref_matcher/indexes/ror_organizations/__init__.py
|
|
29
29
|
crossref_matcher/indexes/ror_organizations/create_index.py
|
|
30
30
|
crossref_matcher/indexes/ror_organizations/index_data.py
|
|
31
|
-
crossref_matcher/indexes/ror_organizations/
|
|
31
|
+
crossref_matcher/indexes/ror_organizations/opensearch_utils.py
|
|
32
32
|
crossref_matcher/indexes/ror_organizations/ror_zenodo_api.py
|
|
33
33
|
crossref_matcher/matching/__init__.py
|
|
34
34
|
crossref_matcher/matching/http_utils.py
|
crossref_matcher-1.3.1/crossref_matcher/indexes/ror_organizations/ror_opensearch_update_dag.py
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
"""Airflow DAG to keep the ROR OpenSearch index up to date."""
|
|
2
|
-
|
|
3
|
-
import base64
|
|
4
|
-
import boto3
|
|
5
|
-
|
|
6
|
-
from airflow.decorators import dag, task
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from datetime import timedelta
|
|
9
|
-
from opensearchpy import (
|
|
10
|
-
OpenSearch,
|
|
11
|
-
RequestsHttpConnection,
|
|
12
|
-
AWSV4SignerAuth,
|
|
13
|
-
NotFoundError,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
import logging
|
|
17
|
-
from typing import Any
|
|
18
|
-
|
|
19
|
-
from crossref_matcher.indexes.ror_organizations.ror_zenodo_api import (
|
|
20
|
-
get_ror_data_dump_metadata,
|
|
21
|
-
)
|
|
22
|
-
from crossref_matcher.indexes.ror_organizations.create_index import (
|
|
23
|
-
index_body,
|
|
24
|
-
initialize_index,
|
|
25
|
-
)
|
|
26
|
-
from crossref_matcher.indexes.ror_organizations.index_data import (
|
|
27
|
-
download_ror_data_and_update_index,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
logger = logging.getLogger(__name__)
|
|
31
|
-
|
|
32
|
-
REGION = "us-east-1"
|
|
33
|
-
INDEX = "organization"
|
|
34
|
-
INDEX_BATCH_SIZE = 400
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def get_secret(secret_name: str) -> str | bytes:
|
|
38
|
-
"""Retrieve a secret value from AWS Secrets Manager."""
|
|
39
|
-
session = boto3.session.Session()
|
|
40
|
-
client = session.client(service_name="secretsmanager", region_name=REGION)
|
|
41
|
-
|
|
42
|
-
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
|
|
43
|
-
if "SecretString" in get_secret_value_response:
|
|
44
|
-
return get_secret_value_response["SecretString"]
|
|
45
|
-
else:
|
|
46
|
-
return base64.b64decode(get_secret_value_response["SecretBinary"])
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def get_es_client() -> OpenSearch:
|
|
50
|
-
"""Create an authenticated OpenSearch client using AWS credentials."""
|
|
51
|
-
credentials = boto3.Session().get_credentials()
|
|
52
|
-
auth = AWSV4SignerAuth(credentials, REGION, "es")
|
|
53
|
-
|
|
54
|
-
return OpenSearch(
|
|
55
|
-
hosts=[{"host": get_secret("es-host-matching"), "port": 443}],
|
|
56
|
-
http_auth=auth,
|
|
57
|
-
use_ssl=True,
|
|
58
|
-
verify_certs=True,
|
|
59
|
-
connection_class=RequestsHttpConnection,
|
|
60
|
-
pool_maxsize=20,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
@dag(
|
|
65
|
-
schedule_interval="@daily",
|
|
66
|
-
catchup=False,
|
|
67
|
-
dagrun_timeout=timedelta(hours=10),
|
|
68
|
-
start_date=datetime(2026, 1, 3),
|
|
69
|
-
tags=["experiment", "ror", "matching"],
|
|
70
|
-
)
|
|
71
|
-
def update_ror_index():
|
|
72
|
-
@task()
|
|
73
|
-
def fetch_ror_metadata() -> dict[str, Any]:
|
|
74
|
-
"""Fetch metadata for the latest ROR data dump from Zenodo."""
|
|
75
|
-
return get_ror_data_dump_metadata()
|
|
76
|
-
|
|
77
|
-
@task.short_circuit()
|
|
78
|
-
def is_update_needed(metadata: dict[str, Any]) -> bool:
|
|
79
|
-
"""Return True if the index checksum differs from the latest dump."""
|
|
80
|
-
ror_checksum = metadata["checksum"]
|
|
81
|
-
es_client = get_es_client()
|
|
82
|
-
|
|
83
|
-
# # FOR TESTING: RUN THIS TO FORCE UPDATE, OTHERWISE COMMENT OUT
|
|
84
|
-
# index_metadata = {
|
|
85
|
-
# "target_data": "",
|
|
86
|
-
# "ror_data_dump_checksum": "",
|
|
87
|
-
# "ror_data_dump_doi": "",
|
|
88
|
-
# }
|
|
89
|
-
# body = {"_meta": index_metadata}
|
|
90
|
-
# es_client.indices.put_mapping(index=INDEX, body=body)
|
|
91
|
-
|
|
92
|
-
try:
|
|
93
|
-
mapping = es_client.indices.get_mapping(index=INDEX)
|
|
94
|
-
except NotFoundError:
|
|
95
|
-
return True
|
|
96
|
-
meta = mapping[INDEX]["mappings"].get("_meta", {})
|
|
97
|
-
current_checksum = meta.get("ror_data_dump_checksum", "")
|
|
98
|
-
return current_checksum != ror_checksum
|
|
99
|
-
|
|
100
|
-
@task()
|
|
101
|
-
def create_index_if_not_exists():
|
|
102
|
-
es_client = get_es_client()
|
|
103
|
-
|
|
104
|
-
index_exists = es_client.indices.exists(index=INDEX)
|
|
105
|
-
|
|
106
|
-
if not index_exists:
|
|
107
|
-
index_body_content = index_body()
|
|
108
|
-
response = initialize_index(INDEX, es_client, index_body_content)
|
|
109
|
-
logger.info(f"Created index '{INDEX}': {response}")
|
|
110
|
-
|
|
111
|
-
@task
|
|
112
|
-
def download_and_update(metadata: dict[str, Any]) -> None:
|
|
113
|
-
"""Download the ROR data dump and update the index."""
|
|
114
|
-
es_client = get_es_client()
|
|
115
|
-
download_ror_data_and_update_index(metadata, es_client)
|
|
116
|
-
|
|
117
|
-
metadata = fetch_ror_metadata()
|
|
118
|
-
update_needed = is_update_needed(metadata)
|
|
119
|
-
# if update_needed is false, the DAG will stop here
|
|
120
|
-
|
|
121
|
-
update_needed >> create_index_if_not_exists() >> download_and_update(metadata)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
workflow = update_ror_index()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.3.1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/evaluation/dataset_ingest.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/affiliation/__init__.py
RENAMED
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/resources/data/models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/funder/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/preprint/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher/strategies/reference/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{crossref_matcher-1.3.1 → crossref_matcher-1.3.2}/crossref_matcher.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|