Skip to content

Commit fed5b70

Browse files
committed
Merge branch 'upstream/release53' into bbc-release53
# Conflicts: # meteor/package.json # meteor/server/publications/lib/rundownsObserver.ts # meteor/yarn.lock # packages/job-worker/package.json # packages/job-worker/src/ingest/__tests__/syncChangesToPartInstance.test.ts # packages/job-worker/src/ingest/syncChangesToPartInstance.ts # packages/job-worker/src/playout/snapshot.ts # packages/webui/src/client/ui/RundownView/RundownRightHandControls.tsx # packages/yarn.lock
2 parents 9e79a9a + 6f853de commit fed5b70

File tree

55 files changed

+5745
-855
lines changed

Some content is hidden

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

55 files changed

+5745
-855
lines changed

.github/workflows/node.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ jobs:
252252
echo "image=$image" >> $GITHUB_OUTPUT
253253
- name: Trivy scanning
254254
if: steps.check-build-and-push.outputs.enable == 'true' && steps.check-ghcr.outputs.enable == 'true' && steps.ghcr-tag.outputs.tags != 0
255-
uses: aquasecurity/trivy-action@0.29.0
255+
uses: aquasecurity/trivy-action@0.30.0
256256
env:
257257
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
258258
with:
@@ -405,7 +405,7 @@ jobs:
405405
echo "image=$image" >> $GITHUB_OUTPUT
406406
- name: Trivy scanning
407407
if: steps.check-build-and-push.outputs.enable == 'true' && steps.check-ghcr.outputs.enable == 'true' && steps.ghcr-tag.outputs.tags != 0
408-
uses: aquasecurity/trivy-action@0.29.0
408+
uses: aquasecurity/trivy-action@0.30.0
409409
env:
410410
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
411411
with:

.github/workflows/trivy.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717

1818
steps:
1919
- name: Run Trivy vulnerability scanner (json)
20-
uses: aquasecurity/trivy-action@0.29.0
20+
uses: aquasecurity/trivy-action@0.30.0
2121
env:
2222
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
2323
with:
@@ -26,7 +26,7 @@ jobs:
2626
output: "${{ matrix.image }}-trivy-scan-results.json"
2727

2828
- name: Run Trivy vulnerability scanner (table)
29-
uses: aquasecurity/trivy-action@0.29.0
29+
uses: aquasecurity/trivy-action@0.30.0
3030
env:
3131
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
3232
with:
@@ -44,7 +44,7 @@ jobs:
4444
echo $CODE_BLOCK >> $GITHUB_STEP_SUMMARY
4545
4646
- name: Run Trivy in GitHub SBOM mode and submit results to Dependency Graph
47-
uses: aquasecurity/trivy-action@0.29.0
47+
uses: aquasecurity/trivy-action@0.30.0
4848
env:
4949
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
5050
with:

meteor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"object-path": "^0.11.8",
6868
"p-lazy": "^3.1.0",
6969
"semver": "^7.6.3",
70-
"superfly-timeline": "9.1.0",
70+
"superfly-timeline": "9.1.2",
7171
"threadedclass": "^1.2.2",
7272
"timecode": "0.0.4",
7373
"type-fest": "^4.33.0",

meteor/server/publications/buckets.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ meteorPublish(
5151
return BucketAdLibs.findWithCursor(selector, {
5252
projection: {
5353
ingestInfo: 0, // This is a large blob, and is not of interest to the UI
54+
privateData: 0,
5455
},
5556
})
5657
}
@@ -76,6 +77,7 @@ meteorPublish(
7677
return BucketAdLibActions.findWithCursor(selector, {
7778
projection: {
7879
ingestInfo: 0, // This is a large blob, and is not of interest to the UI
80+
privateData: 0,
7981
},
8082
})
8183
}

meteor/yarn.lock

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ __metadata:
11601160
mongodb: "npm:^6.12.0"
11611161
p-lazy: "npm:^3.1.0"
11621162
p-timeout: "npm:^4.1.0"
1163-
superfly-timeline: "npm:9.1.0"
1163+
superfly-timeline: "npm:9.1.2"
11641164
threadedclass: "npm:^1.2.2"
11651165
tslib: "npm:^2.8.1"
11661166
type-fest: "npm:^4.33.0"
@@ -1191,7 +1191,7 @@ __metadata:
11911191
resolution: "@sofie-automation/shared-lib@portal:../packages/shared-lib::locator=automation-core%40workspace%3A."
11921192
dependencies:
11931193
"@mos-connection/model": "npm:^4.2.2"
1194-
timeline-state-resolver-types: "npm:9.3.0-release52.0"
1194+
timeline-state-resolver-types: "npm:9.3.0-release52.2"
11951195
tslib: "npm:^2.8.1"
11961196
type-fest: "npm:^4.33.0"
11971197
languageName: node
@@ -2291,7 +2291,7 @@ __metadata:
22912291
prettier: "npm:^2.8.8"
22922292
semver: "npm:^7.6.3"
22932293
standard-version: "npm:^9.5.0"
2294-
superfly-timeline: "npm:9.1.0"
2294+
superfly-timeline: "npm:9.1.2"
22952295
threadedclass: "npm:^1.2.2"
22962296
timecode: "npm:0.0.4"
22972297
ts-jest: "npm:^29.2.5"
@@ -10152,12 +10152,12 @@ __metadata:
1015210152
languageName: node
1015310153
linkType: hard
1015410154

10155-
"superfly-timeline@npm:9.1.0":
10156-
version: 9.1.0
10157-
resolution: "superfly-timeline@npm:9.1.0"
10155+
"superfly-timeline@npm:9.1.2":
10156+
version: 9.1.2
10157+
resolution: "superfly-timeline@npm:9.1.2"
1015810158
dependencies:
1015910159
tslib: "npm:^2.6.0"
10160-
checksum: 10/0c63e6d582570c07f3b6395c9907cfe5c3a1e1125814efc2a6b927c6e774f33cc0081b99442419e75ee00d84b5847aca44bcce03cf70cb49a611e0973e2bdaba
10160+
checksum: 10/f77552cb8b4faab5d13aa88da364498c90d5117427af739fa456d73acd26075fe2e04cc227b8d58d45a4684af7115c24a7e5867c85479a2c0aba3f43b6230367
1016110161
languageName: node
1016210162
linkType: hard
1016310163

@@ -10332,12 +10332,12 @@ __metadata:
1033210332
languageName: node
1033310333
linkType: hard
1033410334

10335-
"timeline-state-resolver-types@npm:9.3.0-release52.0":
10336-
version: 9.3.0-release52.0
10337-
resolution: "timeline-state-resolver-types@npm:9.3.0-release52.0"
10335+
"timeline-state-resolver-types@npm:9.3.0-release52.2":
10336+
version: 9.3.0-release52.2
10337+
resolution: "timeline-state-resolver-types@npm:9.3.0-release52.2"
1033810338
dependencies:
1033910339
tslib: "npm:^2.6.3"
10340-
checksum: 10/162d765cb3f3a673e284ed942aa355c7ab136f092989f28626f73def5f9878fdff763160e3372c8b5da681c9bfdaf104b02c4879bfadbd70fa699a8403920261
10340+
checksum: 10/2f50474e96d6f10d085788b59c2a8a2bedcf8511646424afcb9c2b421798e689894028629f0c55d0b76dc5f543cba06367c7be93c2662608a3804f60c108ded2
1034110341
languageName: node
1034210342
linkType: hard
1034310343

packages/documentation/docs/for-developers/contribution-guidelines.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,22 @@ Before you start, there are a few things you should know:
3030

3131
**Minor changes** (most bug fixes and small features) can be submitted directly as pull requests to the appropriate official repo.
3232

33-
However, Sofie is a big project with many differing users and use cases. **Larger changes** might be more difficult to merge into an official repository if NRK has not been made aware of their existence beforehand. To facilitate a timely handling of larger contributions, there’s a workflow intended to keep an open dialogue between all interested parties:
33+
However, Sofie is a big project with many differing users and use cases. **Larger changes** may be difficult to merge into an official repository if NRK and other contributors have not been made aware of their existence beforehand. Since figuring out what side-effects a new feature or a change may have for other Sofie users can be tricky, we advise opening an RFC issue (_Request for Comments_) early in your process. Good moments to open an RFC include:
34+
* When a user need is identified and described
35+
* When you have a rough idea about how a feature may be implemented
36+
* When you have a sketch of how a feature could look like to the user
37+
38+
To facilitate timely handling of larger contributions, there’s a workflow intended to keep an open dialogue between all interested parties:
3439

3540
1. Contributor opens an RFC (as a _GitHub issue_) in the appropriate repository.
3641
2. NRK evaluates the RFC, usually within a week.
37-
3. (If needed) NRK establishes contact with the RFC author, who will be invited to a workshop where the RFC is discussed. Meeting notes are published publicly on the RFC thread.
38-
4. The contributor references the RFC when a pull request is ready.
42+
3. If needed, NRK establishes contact with the RFC author, who will be invited to a workshop where the RFC is discussed. Meeting notes are published publicly on the RFC thread.
43+
4. Discussions about the RFC continue as needed, either in workshops or in comments in the RFC thread.
44+
5. The contributor references the RFC when a pull request is ready.
45+
46+
It will be very helpful if your RFC includes specific use-cases that you are facing. Providing a background on how your users are using Sofie can clear up situations in which certain phrases or processes may be ambiguous. If during your process you have already identified various solutions as favorable or unfavorable, offering this context will move the discussion further still.
47+
48+
Via the RFC process, we're looking to maximize involvement from various stakeholders, so you probably don't need to come up with a very detailed design of your proposed change or feature in the RFC. An end-user oriented description will be most valuable in creating a constructive dialogue, but don't shy away from also adding a more technical description, if you find that will convey your ideas better.
3949

4050
### Base contributions on the in-development branch
4151
In order to facilitate merging, we ask that contributions are based on the latest (at the time of the pull request) _in-development_ branch (often named `release*`).
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Manipulating Ingest Data
2+
3+
In Sofie we receive the rundown from an NRCS in the form of the `IngestRundown`, `IngestSegment` and `IngestPart` types. ([Source Code](https://github.com/nrkno/sofie-core/blob/master/packages/shared-lib/src/peripheralDevice/ingest.ts))
4+
These are passed into the `getRundown` or `getSegment` blueprints methods to transform them into a Rundown that Sofie can display and play.
5+
6+
At times it can be useful to manipulate this data before it gets passed into these methods. This wants to be done before `getSegment` in order to limit the scope of the re-generation needed. We could have made it so that `getSegment` is able to view the whole `IngestRundown`, but that would mean that any change to the `IngestRundown` would require re-generating every segment. This would be costly and could have side effects.
7+
8+
A new method `processIngestData` was added to transform the `NRCSIngestRundown` into a `SofieIngestRundown`. The types of the two are the same, so implementing the `processIngestData` method is optional, with the default being to pass through the NRCS rundown unchanged. (There is an exception here for MOS, which is explained below).
9+
10+
The basic implementation of this method which simply propogates nrcs changes is:
11+
12+
```ts
13+
function processIngestData(
14+
context: IProcessIngestDataContext,
15+
mutableIngestRundown: MutableIngestRundown<any, any, any>,
16+
nrcsIngestRundown: IngestRundown,
17+
previousNrcsIngestRundown: IngestRundown | undefined,
18+
changes: NrcsIngestChangeDetails | UserOperationChange
19+
) {
20+
if (changes.source === 'ingest') {
21+
blueprintContext.defaultApplyIngestChanges(mutableIngestRundown, nrcsIngestRundown, changes)
22+
}
23+
}
24+
```
25+
26+
In this method, the key part is the `mutableIngestRundown` which is the `IngestRundown` that will get used for `getRundown` and `getSegment` later. It is a class with various mutator methods which allows Sofie to cheaply check what has changed and know what needs to be regenerated. (We did consider performing deep diffs, but were concerned about the cost of diffing these very large rundown objects).
27+
This object internally contains an `IngestRundown`.
28+
29+
The `nrcsIngestRundown` parameter is the full `IngestRundown` as seen by the NRCS. The `previousNrcsIngestRundown` parameter is the `nrcsIngestRundown` from the previous call. This is to allow you to perform any comparisons between the data that may be useful.
30+
31+
The `changes` object is a structure that defines what the NRCS provided changes for. The changes have already been applied onto the `nrcsIngestRundown`, this provides a description of what/where the changes were applied to.
32+
33+
Finally, the `blueprintContext.defaultApplyIngestChanges` call is what performs the 'magic'. Inside of this it is interpreting the `changes` object, and calling the appropriate methods on `mutableIngestRundown`. It is expected that this logic should be able to handle most use cases, but there may be some where they need something custom, so it is completely possible to reimplement inside blueprints.
34+
35+
So far this has ignored that the `changes` object can be of type `UserOperationChange`; this is explained below.
36+
37+
## Modifying NRCS Ingest Data
38+
39+
MOS does not have Segments, to handle this Sofie creates a Segment and Part for each MOS Story, expecting them to be grouped later if needed.
40+
41+
In the past Sofie has had a hardcoded grouping logic, based on how NRK define this as a prefix in the Part names. Obviously this doesn't work for everyone, so this needed to be made more customisable. (This is still the default behaviour when `processIngestData` is not implemented)
42+
43+
To perform the NRK grouping behaviour the following implementation can be used:
44+
45+
```ts
46+
function processIngestData(
47+
context: IProcessIngestDataContext,
48+
mutableIngestRundown: MutableIngestRundown<any, any, any>,
49+
nrcsIngestRundown: IngestRundown,
50+
previousNrcsIngestRundown: IngestRundown | undefined,
51+
changes: NrcsIngestChangeDetails | UserOperationChange
52+
) {
53+
if (changes.source === 'ingest') {
54+
// Group parts by interpreting the slug to be in the form `SEGMENTNAME;PARTNAME`
55+
const groupedResult = context.groupMosPartsInRundownAndChangesWithSeparator(
56+
nrcsIngestRundown,
57+
previousNrcsIngestRundown,
58+
ingestRundownChanges.changes,
59+
';' // Backwards compatibility
60+
)
61+
62+
context.defaultApplyIngestChanges(
63+
mutableIngestRundown,
64+
groupedResult.nrcsIngestRundown,
65+
groupedResult.ingestChanges
66+
)
67+
}
68+
}
69+
```
70+
71+
There is also a helper method for doing your own logic:
72+
73+
```ts
74+
function processIngestData(
75+
context: IProcessIngestDataContext,
76+
mutableIngestRundown: MutableIngestRundown<any, any, any>,
77+
nrcsIngestRundown: IngestRundown,
78+
previousNrcsIngestRundown: IngestRundown | undefined,
79+
changes: NrcsIngestChangeDetails | UserOperationChange
80+
) {
81+
if (changes.source === 'ingest') {
82+
// Group parts by some custom logic
83+
const groupedResult = context.groupPartsInRundownAndChanges(
84+
nrcsIngestRundown,
85+
previousNrcsIngestRundown,
86+
ingestRundownChanges.changes,
87+
(segments) => {
88+
// TODO - perform the grouping here
89+
return segmentsAfterMyChanges
90+
}
91+
)
92+
93+
context.defaultApplyIngestChanges(
94+
mutableIngestRundown,
95+
groupedResult.nrcsIngestRundown,
96+
groupedResult.ingestChanges
97+
)
98+
}
99+
}
100+
```
101+
102+
Both of these return a modified `nrcsIngestRundown` with the changes applied, and a new `changes` object which is similarly updated to match the new layout.
103+
104+
You can of course do any portions of this yourself if you desire.
105+
106+
## User Edits
107+
108+
In some cases, it can be beneficial to allow the user to perform some editing of the Rundown from within the Sofie UI. AdLibs and AdLib Actions can allow for some of this to be done in the current and next Part, but this is limited and doesn't persist when re-running the Part.
109+
110+
The idea here is that the UI will be given some descriptors on operations it can perform, which will then make calls to `processIngestData` so that they can be applied to the IngestRundown. Doing it at this level allows things to persist and for decisions to be made by blueprints over how to merge the changes when an update for a Part is received from the NRCS.
111+
112+
This page doesn't go into how to define the editor for the UI, just how to handle the operations.
113+
114+
There are a few Sofie defined definitions of operations, but it is also expected that custom operations will be defined. You can check the Typescript types for the builtin operations that you might want to handle.
115+
116+
For example, it could be possible for Segments to be locked, so that any NRCS changes for them are ignored.
117+
118+
```ts
119+
function processIngestData(
120+
context: IProcessIngestDataContext,
121+
mutableIngestRundown: MutableIngestRundown<any, any, any>,
122+
nrcsIngestRundown: IngestRundown,
123+
previousNrcsIngestRundown: IngestRundown | undefined,
124+
changes: NrcsIngestChangeDetails | UserOperationChange
125+
) {
126+
if (changes.source === 'ingest') {
127+
for (const segment of mutableIngestRundown.segments) {
128+
delete ingestRundownChanges.changes.segmentChanges[segment.externalId]
129+
// TODO - does this need to revert nrcsIngestRundown too?
130+
}
131+
132+
blueprintContext.defaultApplyIngestChanges(mutableIngestRundown, nrcsIngestRundown, changes)
133+
} else if (changes.source === 'user') {
134+
if (changes.operation.id === 'lock-segment') {
135+
mutableIngestRundown.getSegment(changes.operationTarget.segmentExternalId)?.setUserEditState('locked', true)
136+
}
137+
}
138+
}
139+
```

0 commit comments

Comments
 (0)