Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
b1b4547
Merge pull request #491 from NYPL/main
charmingduchess Jun 2, 2025
7685722
Override agg-self-filtering behavior for open search
nonword Jul 10, 2025
472331e
Merge branch 'NOREF-filter-self-filtering-fix' into qa2
nonword Jul 10, 2025
c784247
Merge pull request #597 from NYPL/NOREF/bnf-test
danamansana Dec 10, 2025
26e0a15
Merge pull request #606 from NYPL/NOREF/bnf-exclude-query-term-parent…
danamansana Dec 18, 2025
9534528
Merge pull request #607 from NYPL/NOREF/bnf-exclude-query-term-parent…
danamansana Dec 18, 2025
7d1612e
Merge pull request #638 from NYPL/main
charmingduchess Feb 6, 2026
5d3bf7d
fix gha dep
charmingduchess Feb 6, 2026
b2a79b8
Merge branch 'SC-5164/delivery-inegration-test' into qa2
charmingduchess Feb 6, 2026
ff32619
gha
charmingduchess Feb 6, 2026
ffe1b30
update gha invocation
charmingduchess Feb 9, 2026
c389071
config aws in integration test
charmingduchess Feb 9, 2026
817a05f
update gha workflows
charmingduchess Feb 9, 2026
15ddf08
Merge branch 'NOREF/nyql-for-qa2' into merge-nyql
danamansana Mar 10, 2026
d99276f
Merge pull request #665 from NYPL/qa2-nyql
danamansana Mar 10, 2026
f9a0250
Merge main
danamansana Mar 10, 2026
691b974
Fix deploy yaml
danamansana Mar 10, 2026
fd33073
Merge pull request #666 from NYPL/qa2-nyql
danamansana Mar 10, 2026
ca8a4d1
Merge pull request #686 from NYPL/scc-5168
danamansana Mar 19, 2026
34a399e
Merge pull request #687 from NYPL/scc-5168
danamansana Mar 19, 2026
753ca86
Merge branch 'scc-5168' into qa2
danamansana Mar 19, 2026
d4c655a
Merge branch 'scc-5168' into qa2
danamansana Mar 20, 2026
831760a
Add series/genre search scopes and tests
7emansell Apr 7, 2026
19ec764
no parallel genreForm
7emansell Apr 7, 2026
3316e8f
trigger rollback with integration-test failure
charmingduchess Apr 10, 2026
a19d88f
ensure int test failure
charmingduchess Apr 10, 2026
4ba6d0d
failure to pass linting
charmingduchess Apr 10, 2026
a5fa996
Merge pull request #710 from NYPL/test-auto-rollback
charmingduchess Apr 10, 2026
9f82e54
Merge branch 'qa2' into test-auto-rollback
charmingduchess Apr 10, 2026
69d493e
add yml to remove in qa2 merge conflict
charmingduchess Apr 10, 2026
a8df84b
rm test and deploy
charmingduchess Apr 10, 2026
eca7039
update gha workflows
charmingduchess Feb 9, 2026
b8bdb99
rm test and deploy
charmingduchess Apr 10, 2026
47d65d2
Merge branch 'qa2' into main
charmingduchess Apr 10, 2026
6d4a350
Merge pull request #711 from NYPL/main
charmingduchess Apr 10, 2026
d2b9efd
hard code qa2 for now
charmingduchess Apr 10, 2026
86ad6db
t:Merge branch 'main' into qa2
charmingduchess Apr 10, 2026
0e09e07
Merge branch 'qa2' into test-auto-rollback
charmingduchess Apr 10, 2026
3de6b01
&ai pass branch from deploy script
charmingduchess Apr 10, 2026
41d9d24
&ai more gha refactor
charmingduchess Apr 10, 2026
7940c60
more gha refactor
charmingduchess Apr 10, 2026
77ae289
fix qa2 reference
charmingduchess Apr 10, 2026
962f9b4
&ai run rollback on failure
charmingduchess Apr 10, 2026
dfaf858
uncomment integration tests
charmingduchess Apr 10, 2026
3f9f1e2
make it for all branches
charmingduchess Apr 10, 2026
dd201ff
rm addition from qa2
charmingduchess Apr 10, 2026
254a0ec
rm production from rollback flow
charmingduchess Apr 13, 2026
f8a715b
rename rollback yml
charmingduchess Apr 13, 2026
7be3186
merge changes
charmingduchess Apr 13, 2026
1b33e66
Merge pull request #702 from NYPL/SCC-5194/series-scope
7emansell Apr 13, 2026
deef704
Merge pull request #712 from NYPL/test-auto-rollback
charmingduchess Apr 13, 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
55 changes: 55 additions & 0 deletions .github/workflows/deploy-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Deploy Image

on:
workflow_call:
inputs:
env_tag:
required: true
type: string
image_tag:
required: true
type: string

jobs:
deploy:
permissions:
id-token: write
contents: read
runs-on: ubuntu-latest
env:
ENV_TAG: ${{ inputs.env_tag }}
ECR_REPOSITORY: discovery-api
steps:
- name: Checkout repo
uses: actions/checkout@v3

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::946183545209:role/GithubActionsDeployerRole
aws-region: us-east-1

- name: Log in to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Back up previous image for rollback
run: |
MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="${ENV_TAG}-latest" --output json | jq --raw-output --join-output '.images[0].imageManifest')
PREVIOUS_MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="${ENV_TAG}-previous" --output json | jq --raw-output --join-output '.images[0].imageManifest')
if [ "$MANIFEST" != "$PREVIOUS_MANIFEST" ]; then
aws ecr put-image --repository-name $ECR_REPOSITORY --image-tag "${ENV_TAG}-previous" --image-manifest "$MANIFEST"
fi

- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:${{ inputs.image_tag }} .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:${{ inputs.image_tag }}
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:${{ inputs.image_tag }} $ECR_REGISTRY/$ECR_REPOSITORY:${ENV_TAG}-latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:${ENV_TAG}-latest

- name: Force ECS Update
run: |
aws ecs update-service --cluster discovery-api-${ENV_TAG} --service discovery-api-${ENV_TAG} --force-new-deployment
57 changes: 22 additions & 35 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy
name: Test-Deploy-Int-Roll

on:
push:
Expand All @@ -21,40 +21,27 @@ jobs:
permissions:
id-token: write
contents: read
runs-on: ubuntu-latest
needs: tests
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: ./.github/workflows/deploy-image.yml
with:
env_tag: ${{ github.ref_name }}
image_tag: ${{ github.sha }}

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::946183545209:role/GithubActionsDeployerRole
aws-region: us-east-1

- name: Log in to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Back up previous image for rollback
run: |
MANIFEST=$(aws ecr batch-get-image --repository-name ${{ env.ECR_REPOSITORY }} --image-ids imageTag="${{ env.ENV_TAG }}-latest" --output json | jq --raw-output --join-output '.images[0].imageManifest')
PREVIOUS_MANIFEST=$(aws ecr batch-get-image --repository-name ${{ env.ECR_REPOSITORY }} --image-ids imageTag="${{ env.ENV_TAG }}-previous" --output json | jq --raw-output --join-output '.images[0].imageManifest')
if [ "$MANIFEST" != "$PREVIOUS_MANIFEST" ]; then
aws ecr put-image --repository-name ${{ env.ECR_REPOSITORY }} --image-tag "${{ env.ENV_TAG }}-previous" --image-manifest "$MANIFEST"
fi

- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG .
docker push $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG
docker tag $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:${{ env.ENV_TAG }}-latest
docker push $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:${{ env.ENV_TAG }}-latest
smoke-test:
permissions:
id-token: write
contents: read
needs: deploy
uses: ./.github/workflows/integration-tests.yml
with:
branch: ${{ github.ref_name }}

- name: Force ECS Update
run: |
aws ecs update-service --cluster discovery-api-${{ env.ENV_TAG }} --service discovery-api-${{ env.ENV_TAG }} --force-new-deployment
rollback:
permissions:
id-token: write
contents: read
needs: smoke-test
if: ${{ failure() && needs.smoke-test.result == 'failure' && github.ref_name != 'production' }}
uses: ./.github/workflows/rollback-qa2.yml
with:
branch: ${{ github.ref_name }}
11 changes: 6 additions & 5 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
name: Run Smoke Tests

on:
workflow_run:
workflows: ["Deploy"]
types: [completed]
branches: [production, qa]
workflow_call:
inputs:
branch:
required: true
type: string

permissions:
id-token: write
contents: read

env:
ENV: ${{ github.event.workflow_run.head_branch }}
ENV: ${{ inputs.branch }}

jobs:
integration-test:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
name: Rollback qa2
name: Rollback ${{inputs.branch}}

on:
workflow_dispatch:

workflow_call:
inputs:
branch:
required: true
type: string
jobs:
# Rollback job in case of failure (Revert qa to the previous task definition)
rollback:
Expand Down Expand Up @@ -36,10 +39,10 @@ jobs:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: discovery-api
run: |
docker pull $ECR_REGISTRY/$ECR_REPOSITORY:qa2-previous
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:qa2-previous $ECR_REGISTRY/$ECR_REPOSITORY:qa2-latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:qa2-latest
docker pull $ECR_REGISTRY/$ECR_REPOSITORY:${{inputs.branch}}-previous
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:${{inputs.branch}}-previous $ECR_REGISTRY/$ECR_REPOSITORY:${{inputs.branch}}-latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:${{inputs.branch}}-latest

- name: Force ECS Update
run: |
aws ecs update-service --cluster discovery-api-qa2 --service discovery-api-qa2 --force-new-deployment
aws ecs update-service --cluster discovery-api-${{inputs.branch}} --service discovery-api-${{inputs.branch}} --force-new-deployment
2 changes: 1 addition & 1 deletion lib/api-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const QUOTE_CHARS = '"\u201C\u201D\u201E\u201F\u2033\u2036'
const IN_QUOTES_PATTERN = new RegExp(`^[${QUOTE_CHARS}][^${QUOTE_CHARS}]+[${QUOTE_CHARS}]$`)

class ApiRequest {
static ADVANCED_SEARCH_PARAMS = ['title', 'subject', 'contributor', 'callnumber', 'standard_number']
static ADVANCED_SEARCH_PARAMS = ['title', 'subject', 'contributor', 'callnumber', 'standard_number', 'series', 'genre']
static IDENTIFIER_NUMBER_PARAMS = ['isbn', 'issn', 'lccn', 'oclc']

constructor (params) {
Expand Down
24 changes: 19 additions & 5 deletions lib/elasticsearch/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ const SEARCH_SCOPES = {
'titleAlt.folded',
'uniformTitle.folded',
'titleDisplay.folded',
'seriesStatement.folded',
'contentsTitle.folded',
'donor.folded',
'parallelTitle.folded^5',
'parallelTitleDisplay.folded',
'parallelSeriesStatement.folded',
'parallelTitleAlt.folded',
'parallelCreatorLiteral.folded',
'parallelUniformTitle',
'formerTitle',
'addedAuthorTitle'
'addedAuthorTitle',
'seriesUniformTitle',
'parallelSeriesUniformTitle'
]
},
contributor: {
Expand All @@ -63,7 +63,21 @@ const SEARCH_SCOPES = {
fields: ['subjectLiteral^2', 'subjectLiteral.folded', 'parallelSubjectLiteral.folded']
},
series: {
fields: ['seriesStatement.folded']
fields: [
'series^2',
'series.folded',
'parallelSeries^2',
'parallelSeries.folded',
'seriesUniformTitle',
'parallelSeriesUniformTitle^2',
'parallelSeriesUniformTitle.folded',
'seriesAddedEntry',
'parallelSeriesAddedEntry^2',
'parallelSeriesAddedEntry.folded'
]
},
genre: {
fields: ['genreForm^2', 'genreForm.folded']
},
journal_title: {
fields: null
Expand Down Expand Up @@ -107,7 +121,7 @@ const FILTER_CONFIG = {
titleAlt: { operator: 'match', field: ['titleAlt.raw', 'parallelTitleAlt.raw'], repeatable: true },
uniformTitle: { operator: 'match', field: ['uniformTitle.raw', 'parallelUniformTitle.raw'], repeatable: true },
addedAuthorTitle: { operator: 'match', field: ['addedAuthorTitle.raw', 'parallelAddedAuthorTitle.raw'], repeatable: true },
series: { operator: 'match', field: ['series', 'parallelSeries'], repeatable: true },
series: { operator: 'match', field: ['series', 'parallelSeries', 'seriesUniformTitle', 'parallelSeriesUniformTitle', 'seriesAddedEntry', 'parallelSeriesAddedEntry'], repeatable: true },
placeOfPublication: { operator: 'match', field: ['placeOfPublication', 'parallelPlaceOfPublication'], repeatable: true },
dateFrom: {
operator: 'custom',
Expand Down
36 changes: 36 additions & 0 deletions lib/elasticsearch/elastic-query-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ class ElasticQueryBuilder {
case 'subject':
this.buildSubjectQuery()
break
case 'series':
this.buildSeriesQuery()
break
case 'genre':
this.buildGenreQuery()
break
case 'standard_number':
this.buildStandardNumberQuery()
break
Expand Down Expand Up @@ -163,6 +169,36 @@ class ElasticQueryBuilder {
this.boostSubjectMatches()
}

/**
* Build ES query for 'series' searches
*/
buildSeriesQuery () {
if (!this.request.hasSearch()) return

// Require a basic multi-match on series fields:
this.requireMultiMatch(SEARCH_SCOPES.series.fields)

// Apply common boosts:
this.boostNyplOwned()
this.boostOnSite()
this.boostPopular()
}

/**
* Build ES query for 'genre' searches
*/
buildGenreQuery () {
if (!this.request.hasSearch()) return

// Require a basic multi-match on genre fields:
this.requireMultiMatch(SEARCH_SCOPES.genre.fields)

// Apply common boosts:
this.boostNyplOwned()
this.boostOnSite()
this.boostPopular()
}

applySubjectPrefix () {
const q = this.request.params.subject_prefix
this.query.addMust({
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
},
"scripts": {
"test": "./node_modules/.bin/standard --env mocha && NODE_ENV=test ./node_modules/.bin/mocha test --exit",
"test-integration": "./node_modules/.bin/mocha test/integration",
"start": "node server.js",
"deploy-development": "git checkout development && git pull origin development && eb deploy discovery-api-dev --profile nypl-sandbox",
"deploy-qa": "git checkout qa && git pull origin qa && eb deploy discovery-api-qa --profile nypl-digital-dev",
Expand Down
5 changes: 4 additions & 1 deletion test/api-request.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('ApiRequest', function () {
request = ApiRequest.fromParams({ q: '"toast"' })
expect(request.queryIsFullyQuoted()).to.eq(true)

// Test smart-quotes, the great scorge
// Test smart-quotes, the great scourge
request = ApiRequest.fromParams({ q: '“toast“' })
expect(request.queryIsFullyQuoted()).to.eq(true)

Expand All @@ -54,5 +54,8 @@ describe('ApiRequest', function () {

request = ApiRequest.fromParams({ title: '"toast"', foo: 'bar' })
expect(request.advancedSearchParamsThatAreAlsoScopes()).to.deep.eq(['title'])

request = ApiRequest.fromParams({ series: '"Greek volumes"', foo: 'bar' })
expect(request.advancedSearchParamsThatAreAlsoScopes()).to.deep.eq(['series'])
})
})
Loading
Loading