Skip to content

Commit 7f56b64

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents fe6a835 + 6ce67d0 commit 7f56b64

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+467
-250
lines changed

.github/pull_request_template.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ _Demonstrate any UI / behavioral changes with screenshots or animations._
1717
- [ ] I have added tests that prove my fix is effective or that my feature works
1818
- [ ] I have enabled auto-merge (optional)
1919

20-
## QA testing
20+
## Testing
2121

22-
Testers, use the following instructions on [qa.languageforge.org](https://qa.languageforge.org). Post your findings as a comment and include any meaningful screenshots, etc.
22+
Testers, use the following instructions against our staging environment. Post your findings as a comment and include any meaningful screenshots, etc.
2323

2424
_Describe how to verify your changes and provide any necessary test data._
2525

.github/workflows/integrate-and-deploy.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ jobs:
111111
uses: sillsdev/common-github-actions/install-kubectl@v1
112112
-
113113
run: |
114-
kubectl --context ${{ secrets.kube-context }} set image deployment/app app=${{ needs.integrate.outputs.IMAGE_APP }}
115-
kubectl --context ${{ secrets.kube-context }} set image deployment/next-proxy next-proxy=${{ needs.integrate.outputs.IMAGE_PROXY }}
116-
kubectl --context ${{ secrets.kube-context }} set image deployment/next-app next-app=${{ needs.integrate.outputs.IMAGE_NEXT_APP }}
117-
kubectl --context ${{ secrets.kube-context }} set image deployment/lfmerge lfmerge=${{ needs.integrate.outputs.IMAGE_LFMERGE }}
114+
kubectl --context ${{ secrets.kube-context }} -n languageforge set image deployment/app app=${{ needs.integrate.outputs.IMAGE_APP }}
115+
kubectl --context ${{ secrets.kube-context }} -n languageforge set image deployment/next-proxy next-proxy=${{ needs.integrate.outputs.IMAGE_PROXY }}
116+
kubectl --context ${{ secrets.kube-context }} -n languageforge set image deployment/next-app next-app=${{ needs.integrate.outputs.IMAGE_NEXT_APP }}
117+
kubectl --context ${{ secrets.kube-context }} -n languageforge set image deployment/lfmerge lfmerge=${{ needs.integrate.outputs.IMAGE_LFMERGE }}

CONTRIBUTING.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88

99
### Typical Workflow
1010

11-
1. Create a branch off of `develop`
12-
1. Create a PR back into `develop`
13-
1. Once approved and merged, test those changes on [qa.languageforge.org](https://qa.languageforge.org)
14-
1. Once you are satisfied with the changes, coordinate with the team to deliver those changes to the production environment
15-
1. Team leads will determine when the right time to cut a release, i.e., tag and deploy, typically this should be within a day or two
11+
1. Create a branch off of `develop`
12+
2. Create a PR back into `develop`
13+
3. A reviewer will evaluate the code changes and (more often than not, if deemed necessary) test the changes locally
14+
4. Once approved and merged, test your changes on staging
15+
5. If everything's dandy the card can be moved on to PO sign-off
16+
6. Team leads will determine when the right time to cut a release, i.e., tag and deploy, typically this should be within a day or two
1617

1718
### Production Bugfix Workflow
1819

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ build:
4848
npm install
4949

5050
# ensure we start with a clean ui-dist volume for every build
51-
docker volume rm web-languageforge_lf-ui-dist 2>/dev/null
51+
-docker volume rm web-languageforge_lf-ui-dist 2>/dev/null
5252

5353
docker compose build mail app lfmerge ld-api next-proxy next-app
5454

docker-compose.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ services:
4141
- LDAPI_BASE_URL=http://ld-api:3000/api/v2/
4242
- ENVIRONMENT=development
4343
- WEBSITE=localhost
44-
# - WEBSITE=qa.languageforge.org
4544
- DATABASE=scriptureforge
4645
- MONGODB_CONN=mongodb://db:27017
4746
- MAIL_HOST=mail
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
2+
3+
function verifyDbExists(dbName) {
4+
var database = db.getSiblingDB("admin")
5+
.runCommand({ "listDatabases": 1 })
6+
.databases.find(database => database.name === dbName);
7+
if (!exists) {
8+
throw new Error(`The database "${dbName}" does not exist.`)
9+
}
10+
}
11+
12+
function findEntriesThatUseFieldInDb(fieldPath, dbName, skipVerify) {
13+
skipVerify || verifyDbExists(dbName);
14+
15+
var lexicon = db.getSiblingDB(dbName).getCollection('lexicon');
16+
let matches = [];
17+
if (lexicon) {
18+
var cursor = lexicon.find({[fieldPath]: {"$exists" : true}});
19+
while (cursor.hasNext()) {
20+
var entry = cursor.next();
21+
if (entryHasNonEmptyValueForField(entry, fieldPath)) {
22+
matches.push({db: dbName, entry});
23+
}
24+
}
25+
}
26+
return matches;
27+
}
28+
29+
function findEntriesThatUseFieldInAllDbs(fieldPath, threshold) {
30+
threshold = threshold || 300;
31+
db = db.getSiblingDB("admin");
32+
dbs = db.runCommand({ "listDatabases": 1 }).databases;
33+
var results = [];
34+
35+
for (var i in dbs) {
36+
var database = dbs[i];
37+
var entries = findEntriesThatUseFieldInDb(fieldPath, database.name, true);
38+
results.push(...entries);
39+
if (results.length >= threshold) {
40+
print(`Maxed out at threshold (${threshold}).`)
41+
break;
42+
}
43+
}
44+
return results;
45+
}
46+
47+
function entryHasNonEmptyValueForField(entry, fieldPath) {
48+
if (!entry) {
49+
return false;
50+
}
51+
52+
return navigatePath(entry, fieldPath)
53+
.filter(fieldHasNonEmptyValue).length > 0;
54+
}
55+
56+
function fieldHasNonEmptyValue(field) {
57+
if (!field) {
58+
return false;
59+
}
60+
61+
if (field.value && field.value.trim()) {
62+
return true;
63+
}
64+
65+
for (var inputSystem in field) {
66+
if (field[inputSystem].value && field[inputSystem].value.trim()) {
67+
return true;
68+
}
69+
}
70+
71+
return false;
72+
}
73+
74+
function navigatePath(entry, path) {
75+
if (!entry) {
76+
return [];
77+
}
78+
79+
var step = path.split('.')[0];
80+
var result = entry[step];
81+
if (!result) {
82+
return [];
83+
}
84+
85+
var restPath = path.substring(path.indexOf(".") + 1);
86+
var isLastStep = path === restPath;
87+
if (isLastStep) {
88+
return Array.isArray(result) ? result : [result];
89+
} else {
90+
return Array.isArray(result)
91+
? result.flatMap(value => navigatePath(value, restPath))
92+
: navigatePath(result, restPath);
93+
}
94+
}
95+
96+
function getProjectId(dbName, projects) {
97+
const projectCode = dbName.replace('sf_', '');
98+
var project = projects.findOne({'projectCode': {$eq: projectCode}});
99+
return `${projectCode}::${project._id.toString()}`;
100+
}
101+
102+
function findNonEmptyValuesForField(fieldPath, dbName) {
103+
var results = dbName
104+
? findEntriesThatUseFieldInDb(fieldPath, dbName)
105+
: findEntriesThatUseFieldInAllDbs(fieldPath);
106+
var projects = db.getSiblingDB('scriptureforge').getCollection('projects');
107+
return results.flatMap(result => navigatePath(result.entry, fieldPath)
108+
.filter(fieldHasNonEmptyValue)
109+
.map(field => ({
110+
project: getProjectId(result.db, projects),
111+
entryId: result.entry._id.toString(),
112+
value: field.value || field.values || field,
113+
})));
114+
}
115+
116+
findNonEmptyValuesForField("senses.senseImportResidue");

docker/deployment/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ create-new-deployment-mail:
4343

4444
deploy-staging: deploy-db deploy-mail-staging deploy-app-staging deploy-lfmerge-staging deploy-next-proxy-staging deploy-next-app-staging
4545
deploy-mail-staging:
46-
sed -e s/{{SERVER_HOSTNAME}}/qa.languageforge.org/ mail-deployment.yaml | kubectl apply -f -
46+
sed -e s/{{SERVER_HOSTNAME}}/staging.languageforge.org/ mail-deployment.yaml | kubectl apply -f -
4747
deploy-app-staging:
48-
sed -e s/{{WEBSITE}}/qa.languageforge.org/ app-deployment.yaml \
48+
sed -e s/{{WEBSITE}}/staging.languageforge.org/ app-deployment.yaml \
4949
| sed -e s/{{VERSION}}/$(VERSION_APP)/ | kubectl apply -f -
5050
deploy-lfmerge-staging:
5151
sed -e s/{{VERSION_LFMERGE}}/$(VERSION_LFMERGE)/ lfmerge-deployment.yaml | kubectl apply -f -
5252
deploy-next-proxy-staging:
53-
sed -e s/{{WEBSITE}}/qa.languageforge.org/ next-proxy-deployment.yaml \
53+
sed -e s/{{WEBSITE}}/staging.languageforge.org/ next-proxy-deployment.yaml \
5454
| sed -e s/{{VERSION}}/$(VERSION_PROXY)/ | kubectl apply -f -
5555
deploy-next-app-staging:
5656
sed -e s/{{VERSION}}/$(VERSION_NEXT_APP)/ next-app-deployment.yaml | kubectl apply -f -

docker/next-app/Caddyfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
auto_https off
55
}
66

7+
78
:80 {
89
@next_app_paths {
910
path /_app/*
@@ -20,4 +21,12 @@
2021
}
2122

2223
reverse_proxy {$LEGACY_APP}
24+
25+
# https://developers.google.com/search/docs/crawling-indexing/block-indexing#http-response-header
26+
@staging {
27+
host staging.languageforge.org
28+
}
29+
header @staging {
30+
X-Robots-Tag noindex
31+
}
2332
}

docs/RELEASE.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ Releases are tagged in Git using the naming convention `vYYYY-MM-DD` and Docker
1212

1313
Language Forge is built to run in a containerized environment. Kubernetes is our chosen runtime platform for production. Deployments are automated under the right circumstances using GitHub Actions.
1414

15-
### Staging (QA)
16-
17-
[qa.languageforge.org](https://qa.languageforge.org)
15+
### Staging
1816

1917
Current workflow:
2018

2119
1. merge PR into or make commits on `develop` branch
22-
1. this will kick off the GHA (`.github/workflows/staging.yml`) to build, test and publish the necessary images to Docker Hub (https://hub.docker.com/r/sillsdev/web-languageforge/tags) and deploy this code to the staging environment at https://qa.languageforge.org
20+
1. this will kick off the GHA (`.github/workflows/staging.yml`) to build, test and publish the necessary images to Docker Hub (https://hub.docker.com/r/sillsdev/web-languageforge/tags) and deploy this code to the staging environment.
2321

2422
Staging deployments can be manually run with `VERSION_APP=<some-docker-tag-or-semver> VERSION_PROXY=<some-docker-tag-or-semver> VERSION_NEXT_APP=<some-docker-tag-or-semver> VERSION_LFMERGE=<some-docker-tag-or-semver> make deploy-staging`.
2523

@@ -61,7 +59,7 @@ Since database upgrades are so infrequent, require extra care and a brief outage
6159
1. `make scale-down` and ensure all containers are stopped. It's also a good idea to watch the logs for the `db` container ensuring the shutdown was "clean".
6260
1. `make deploy-db` and ensure configs are applied to the deployment
6361
1. `make scale-up` and ensure all containers start back up. It's also a good idea to watch the logs for the `db` container ensuring the startup was "clean" and the new version is actually running.
64-
1. Verify that the running MongoDB version is in fact the version you expect. Connecting to QA or PROD mongo instance using the `mongosh` client should confirm this (the server version is printed when you connect). You can also check the image name of the deployment you are inspecting.
62+
1. Verify that the running MongoDB version is in fact the version you expect. Connecting to staging or production mongo instance using the `mongosh` client should confirm this (the server version is printed when you connect). You can also check the image name of the deployment you are inspecting.
6563
1. Run the `db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )` command to verify that feature version is set to the previous db version
6664
1. Ensure a recent backup of the mongo databases was successful and is available in case a restore/revert is necessary.
6765
1. To perform the actual upgrade run `db.adminCommand( { setFeatureCompatibilityVersion: "5.0" } )` Change the version to the desired new version number. This operation may take some time to complete as it may trigger an internal data migration on existing collections.

next-app/package-lock.json

Lines changed: 47 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)