Skip to content

Commit e0e65c8

Browse files
authored
Merge pull request #5043 from nulib/deploy/staging
Deploy v10.1.0 to production
2 parents c3b821c + bc9249d commit e0e65c8

Some content is hidden

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

53 files changed

+2752
-1055
lines changed

.github/workflows/deploy.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ jobs:
9999
} >> $GITHUB_OUTPUT
100100
env:
101101
REGISTRY_NAME: ${{ steps.login-ecr.outputs.registry }}
102+
- name: Set Meadow Release Name
103+
id: meadow-release
104+
run: echo "name=meadow-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
102105
- uses: docker/build-push-action@v2
103106
with:
104107
context: ./app
@@ -111,6 +114,7 @@ jobs:
111114
HONEYBADGER_API_KEY_FRONTEND=${{ secrets.HONEYBADGER_API_KEY_FRONTEND }}
112115
HONEYBADGER_ENVIRONMENT=${{ env.DEPLOY_ENV }}
113116
HONEYBADGER_REVISION=${{ github.sha }}
117+
RELEASE_NAME=${{ steps.meadow-release.outputs.name }}
114118
MEADOW_TENANT=${{ env.MEADOW_TENANT }}
115119
MEADOW_VERSION=${{ env.MEADOW_VERSION }}
116120
- name: Upload Source Maps to Honeybadger

app/Dockerfile

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ FROM ${BUILD_IMAGE} AS build
66
LABEL edu.northwestern.library.app=meadow \
77
edu.northwestern.library.cache=true \
88
edu.northwestern.library.stage=deps
9-
ARG HONEYBADGER_API_KEY=
10-
ARG HONEYBADGER_API_KEY_FRONTEND=
11-
ARG HONEYBADGER_ENVIRONMENT=
12-
ARG HONEYBADGER_REVISION=
13-
ARG MEADOW_TENANT=
14-
ARG MEADOW_VERSION=
15-
ENV MIX_ENV=prod
169
RUN mix local.hex --force \
1710
&& mix local.rebar --force
1811
ENV NODE_VERSION=22
@@ -26,6 +19,7 @@ RUN apt update -qq \
2619
&& apt update -qq \
2720
&& apt install -y nodejs \
2821
&& npm install -g npm@$NPM_VERSION
22+
ENV MIX_ENV=prod
2923
COPY . /app
3024
WORKDIR /app
3125
RUN mix deps.get --only prod \
@@ -42,15 +36,25 @@ RUN for flag in $(find . -name .docker-npm); do \
4236
cd -; \
4337
done
4438
WORKDIR /app
39+
ARG HONEYBADGER_API_KEY=
40+
ARG HONEYBADGER_API_KEY_FRONTEND=
41+
ARG HONEYBADGER_ENVIRONMENT=
42+
ARG HONEYBADGER_REVISION=
43+
ARG MEADOW_TENANT=
44+
ARG MEADOW_VERSION=
45+
ARG RELEASE_NAME=
46+
ENV RELEASE_NAME=${RELEASE_NAME}
4547
RUN mix release --overwrite
4648

4749
# Create runtime image
4850
FROM ${RUNTIME_IMAGE}
4951
LABEL edu.northwestern.library.app=meadow \
50-
edu.northwestern.library.stage=runtime
52+
edu.northwestern.library.stage=runtime
5153
RUN apt update -qq && apt install -y curl git jq libssl-dev libncurses5-dev
54+
ARG RELEASE_NAME=
55+
ENV RELEASE_NAME=${RELEASE_NAME}
5256
ENV LANG=C.UTF-8
53-
EXPOSE 4000 4369
57+
EXPOSE 4000 4369 9100-9155
5458
COPY --from=build /app/_build/prod/rel/meadow /app
5559
WORKDIR /app
5660
RUN npm install -g @anthropic-ai/claude-code \

app/assets/js/components/Plan/Panel/Diff.jsx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
toArray,
55
toRows,
66
isCodedTerm,
7+
isNestedCodedTerm,
78
} from "@js/components/Plan/Panel/diff-helpers";
89

910
/**
@@ -43,6 +44,66 @@ const renderCodedTerm = (value) => {
4344
return JSON.stringify(value, null, 0);
4445
};
4546

47+
/**
48+
* Render a notes array
49+
*/
50+
const renderNotes = (notes) => {
51+
if (!Array.isArray(notes) || notes.length === 0) return "—";
52+
53+
return (
54+
<ul>
55+
{notes.map((note, i) => (
56+
<li key={i}>
57+
{note.type?.label && (
58+
<strong>{note.type.label}: </strong>
59+
)}
60+
{note.note || "—"}
61+
</li>
62+
))}
63+
</ul>
64+
);
65+
};
66+
67+
/**
68+
* Render a related_url array
69+
*/
70+
const renderRelatedUrls = (urls) => {
71+
if (!Array.isArray(urls) || urls.length === 0) return "—";
72+
73+
return (
74+
<ul>
75+
{urls.map((item, i) => (
76+
<li key={i}>
77+
{item.label?.label && (
78+
<strong>{item.label.label}: </strong>
79+
)}
80+
{item.url ? (
81+
<a href={item.url} target="_blank" rel="noopener noreferrer">
82+
{item.url}
83+
</a>
84+
) : (
85+
"—"
86+
)}
87+
</li>
88+
))}
89+
</ul>
90+
);
91+
};
92+
93+
/**
94+
* Render a nested coded term field (notes or related_url)
95+
*/
96+
const renderNestedCodedTerm = (path, value) => {
97+
if (path.endsWith("notes")) {
98+
return renderNotes(value);
99+
}
100+
if (path.endsWith("related_url")) {
101+
return renderRelatedUrls(value);
102+
}
103+
// Fallback to generic rendering
104+
return renderGenericValue(value);
105+
};
106+
46107
/**
47108
* Render a generic (non-controlled) value
48109
*/
@@ -104,6 +165,8 @@ const PlanPanelChangesDiff = ({ proposedChanges }) => {
104165
title={change.label}
105166
items={toArray(change.value)}
106167
/>
168+
) : change.nestedCoded ? (
169+
renderNestedCodedTerm(change.path, change.value)
107170
) : isCodedTerm(change.path) ? (
108171
renderCodedTerm(change.value)
109172
) : (

app/assets/js/components/Plan/Panel/diff-helpers.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
WORK_FIELDS,
33
CONTROLLED_TERM_FIELDS,
44
CODED_TERM_FIELDS,
5+
NESTED_CODED_TERM_FIELDS,
56
} from "@js/components/Plan/fields";
67

78
/**
@@ -19,6 +20,11 @@ const isControlled = (path) => CONTROLLED_TERM_FIELDS.has(path);
1920
*/
2021
const isCodedTerm = (path) => CODED_TERM_FIELDS.has(path);
2122

23+
/**
24+
* Determine if a given dotted path is a nested coded term field
25+
*/
26+
const isNestedCodedTerm = (path) => NESTED_CODED_TERM_FIELDS.has(path);
27+
2228
/**
2329
* Lookup a display label from WORK_FIELDS
2430
*/
@@ -80,6 +86,19 @@ const toRows = (changeObj, method) => {
8086
continue;
8187
}
8288

89+
if (isNestedCodedTerm(path)) {
90+
rows.push({
91+
id: `${method}-${path}`,
92+
method,
93+
path,
94+
label: getFieldLabel(path, WORK_FIELDS),
95+
value,
96+
controlled: false,
97+
nestedCoded: true,
98+
});
99+
continue;
100+
}
101+
83102
// Is a primitive value or array
84103
if (value == null || typeof value !== "object" || Array.isArray(value)) {
85104
rows.push({
@@ -102,4 +121,11 @@ const toRows = (changeObj, method) => {
102121
return rows;
103122
};
104123

105-
export { toArray, isControlled, isCodedTerm, getFieldLabel, toRows };
124+
export {
125+
toArray,
126+
isControlled,
127+
isCodedTerm,
128+
isNestedCodedTerm,
129+
getFieldLabel,
130+
toRows,
131+
};

app/assets/js/components/Plan/Panel/diff-helpers.test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ jest.mock("@js/components/Plan/fields", () => {
2222
"descriptive_metadata.rights_statement",
2323
]);
2424

25-
return { WORK_FIELDS, CONTROLLED_TERM_FIELDS, CODED_TERM_FIELDS };
25+
const NESTED_CODED_TERM_FIELDS = new Set([
26+
"descriptive_metadata.notes",
27+
"descriptive_metadata.related_url",
28+
]);
29+
30+
return { WORK_FIELDS, CONTROLLED_TERM_FIELDS, CODED_TERM_FIELDS, NESTED_CODED_TERM_FIELDS };
2631
});
2732

2833
import { toArray, isControlled, getFieldLabel, toRows } from "./diff-helpers";

app/assets/js/components/Plan/fields.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,14 @@ export const CODED_TERM_FIELDS = new Set([
6868
"descriptive_metadata.license",
6969
"descriptive_metadata.rights_statement",
7070
]);
71+
72+
/**
73+
* Set of nested coded term fields by their dotted paths
74+
* These are arrays of objects where each object contains a coded term
75+
* - notes: array of {note: string, type: {id, scheme, label}}
76+
* - related_url: array of {url: string, label: {id, scheme, label}}
77+
*/
78+
export const NESTED_CODED_TERM_FIELDS = new Set([
79+
"descriptive_metadata.notes",
80+
"descriptive_metadata.related_url",
81+
]);

0 commit comments

Comments
 (0)