Skip to content

Commit 96993d0

Browse files
committed
Merge branch 'release51' into test/release51
2 parents 8c16ce8 + d2a3cdf commit 96993d0

File tree

103 files changed

+4454
-335
lines changed

Some content is hidden

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

103 files changed

+4454
-335
lines changed

.github/workflows/node.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ jobs:
9090
CI: true
9191
- name: Send coverage
9292
if: ((github.event_name == 'pull_request') && (!startsWith(github.head_ref, 'release'))) || ((github.event_name == 'push') && (!startsWith(github.ref_name, 'release')))
93-
uses: codecov/codecov-action@v4
93+
uses: codecov/codecov-action@v5
9494
env:
9595
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
9696

@@ -239,7 +239,7 @@ jobs:
239239
echo "image=$image" >> $GITHUB_OUTPUT
240240
- name: Trivy scanning
241241
if: steps.check-build-and-push.outputs.enable == 'true' && steps.check-ghcr.outputs.enable == 'true' && steps.ghcr-tag.outputs.tags != 0
242-
uses: aquasecurity/trivy-action@0.24.0
242+
uses: aquasecurity/trivy-action@0.29.0
243243
env:
244244
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
245245
with:
@@ -390,7 +390,7 @@ jobs:
390390
echo "image=$image" >> $GITHUB_OUTPUT
391391
- name: Trivy scanning
392392
if: steps.check-build-and-push.outputs.enable == 'true' && steps.check-ghcr.outputs.enable == 'true' && steps.ghcr-tag.outputs.tags != 0
393-
uses: aquasecurity/trivy-action@0.24.0
393+
uses: aquasecurity/trivy-action@0.29.0
394394
env:
395395
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
396396
with:
@@ -525,7 +525,7 @@ jobs:
525525
CI: true
526526
- name: Send coverage
527527
if: (matrix.node-version == '16.x' || matrix.send-coverage == true) && ((github.event_name == 'pull_request') && ((!startsWith(github.head_ref, 'release'))) || ((github.event_name == 'push') && (!startsWith(github.ref_name, 'release'))))
528-
uses: codecov/codecov-action@v4
528+
uses: codecov/codecov-action@v5
529529
env:
530530
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
531531

@@ -748,6 +748,6 @@ jobs:
748748
CI: true
749749
- name: Run check
750750
run: |
751-
node scripts/checkForMultipleVersions.mjs
751+
yarn validate:versions
752752
env:
753753
CI: true

.github/workflows/trivy.yml

Lines changed: 34 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Scheduled Trivy Scan
22
on:
33
workflow_dispatch:
44
schedule:
5-
- cron: '0 10 * * 1'
5+
- cron: "0 10 * * 1"
66

77
jobs:
88
trivy:
@@ -17,21 +17,21 @@ jobs:
1717

1818
steps:
1919
- name: Run Trivy vulnerability scanner (json)
20-
uses: aquasecurity/trivy-action@0.24.0
20+
uses: aquasecurity/trivy-action@0.29.0
2121
env:
2222
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
2323
with:
2424
image-ref: ghcr.io/nrkno/sofie-core-${{ matrix.image }}:latest
2525
format: json
26-
output: '${{ matrix.image }}-trivy-scan-results.json'
26+
output: "${{ matrix.image }}-trivy-scan-results.json"
2727

2828
- name: Run Trivy vulnerability scanner (table)
29-
uses: aquasecurity/trivy-action@0.24.0
29+
uses: aquasecurity/trivy-action@0.29.0
3030
env:
3131
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
3232
with:
3333
image-ref: ghcr.io/nrkno/sofie-core-${{ matrix.image }}:latest
34-
output: '${{ matrix.image }}-trivy-scan-results.txt'
34+
output: "${{ matrix.image }}-trivy-scan-results.txt"
3535

3636
- name: Post all scan results to Github Summary as a table
3737
env:
@@ -44,12 +44,12 @@ 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.24.0
47+
uses: aquasecurity/trivy-action@0.29.0
4848
env:
4949
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
5050
with:
51-
format: 'github'
52-
output: 'dependency-results-${{ matrix.image }}.sbom.json'
51+
format: "github"
52+
output: "dependency-results-${{ matrix.image }}.sbom.json"
5353
image-ref: ghcr.io/nrkno/sofie-core-${{ matrix.image }}:latest
5454
github-pat: ${{ secrets.GITHUB_TOKEN }}
5555

@@ -64,46 +64,31 @@ jobs:
6464
echo ${{ env.SUMMARY }}
6565
6666
- name: Send Slack Notification
67-
uses: slackapi/slack-github-action@v1.27.0
67+
uses: slackapi/slack-github-action@v2.0.0
6868
with:
69+
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
70+
webhook-type: incoming-webhook
6971
payload: |
70-
{
71-
"text": "Trivy scan results",
72-
"blocks": [
73-
{
74-
"type": "header",
75-
"text": {
76-
"type": "plain_text",
77-
"text": "Trivy scan results for sofie-core-${{ matrix.image }}:latest"
78-
}
79-
},
80-
{
81-
"type": "section",
82-
"text": {
83-
"type": "mrkdwn",
84-
"text": ":thisisfine: ${{ env.SUMMARY }}"
85-
}
86-
},
87-
{
88-
"type": "section",
89-
"text": {
90-
"type": "mrkdwn",
91-
"text": "Read the full scan results on Github"
92-
},
93-
"accessory": {
94-
"type": "button",
95-
"text": {
96-
"type": "plain_text",
97-
"text": ":github: Scan results",
98-
"emoji": true
99-
},
100-
"value": "workflow_run",
101-
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
102-
"action_id": "button-action"
103-
}
104-
}
105-
]
106-
}
107-
env:
108-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
109-
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
72+
text: "Trivy scan results"
73+
blocks:
74+
- type: "header"
75+
text:
76+
type: "plain_text"
77+
text: "Trivy scan results for sofie-core-${{ matrix.image }}:latest"
78+
- type: "section"
79+
text:
80+
type: "mrkdwn"
81+
text: ":thisisfine: ${{ env.SUMMARY }}"
82+
- type: "section"
83+
text:
84+
type: "mrkdwn"
85+
text: "Read the full scan results on Github"
86+
accessory:
87+
type: "button"
88+
text:
89+
type: "plain_text"
90+
text: ":github: Scan results"
91+
emoji: true
92+
value: "workflow_run"
93+
url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
94+
action_id: "button-action"

meteor/CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
### [1.51.4](///compare/v1.51.3...v1.51.4) (2024-12-04)
6+
7+
8+
### Bug Fixes
9+
10+
* Device Action Studio Context gets lost, Adlib previews are unstable 193815d
11+
* Live Status Gateway Dockerfile (regular) still uses yarn to start 0ae53c4
12+
* release scripts broken on Windows 9636051
13+
* RundownView shows spinner when unMOSing a Rundown from a Playlist 874e85c
14+
15+
### [1.51.2](https://github.com/nrkno/tv-automation-server-core/compare/v1.51.1...v1.51.2) (2024-11-21)
16+
17+
18+
### Bug Fixes
19+
20+
* Include previousPartInstance in check to orphan segments rather than remove them. ([2c113b5](https://github.com/nrkno/tv-automation-server-core/commit/2c113b58b205198d13f0fc7e2114704311eb915b))
21+
* updatePartInstancesSegmentIds: take into account when multiple segments have been merged into one. ([bdab8c4](https://github.com/nrkno/tv-automation-server-core/commit/bdab8c4e4ee1e67a3568cccc98106bb7f1258673))
22+
523
## [1.51.0-in-testing.3](https://github.com/nrkno/sofie-core/compare/v1.51.0-in-testing.2...v1.51.0-in-testing.3) (2024-09-25)
624

725
## [1.51.0-in-testing.2](https://github.com/nrkno/sofie-core/compare/v1.51.0-in-testing.1...v1.51.0-in-testing.2) (2024-09-24)

meteor/client/lib/ReactMeteorData/ReactMeteorData.tsx

Lines changed: 127 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable react/prefer-stateless-function */
22

3-
import React, { useState, useEffect, useRef } from 'react'
3+
import React, { useState, useEffect, useRef, useCallback } from 'react'
44
import { Meteor } from 'meteor/meteor'
55
import { Mongo } from 'meteor/mongo'
66
import { Tracker } from 'meteor/tracker'
@@ -13,6 +13,8 @@ const globalTrackerQueue: Array<Function> = []
1313
let globalTrackerTimestamp: number | undefined = undefined
1414
let globalTrackerTimeout: number | undefined = undefined
1515

16+
const SUBSCRIPTION_TIMEOUT = 1000
17+
1618
/**
1719
* Delay an update to be batched with the global tracker invalidation queue
1820
*/
@@ -370,6 +372,61 @@ export function useTracker<T, K extends undefined | T = undefined>(
370372
return meteorData
371373
}
372374

375+
/**
376+
* A hook to track a boolean state with a sort of histeresis, with preference for `true`. `setState` makes the returned
377+
* `state` be `true` immediately, but `false` only after `resetState` is called and `timeout` elapses. If `setState`
378+
* is called with `true` before `timeout` elapses, then `resetState` is aborted and `state` will remain `ture.
379+
*
380+
* Later `resetState` calls replace earlier unelapsed calls and their timeout periods.
381+
*
382+
* @param {boolean} [initialState=false]
383+
* @return {*} {{
384+
* state: boolean
385+
* setState: (value: boolean) => void
386+
* resetState: (timeout: number) => void
387+
* }}
388+
*/
389+
function useDelayState(initialState = false): {
390+
state: boolean
391+
setState: (value: boolean) => void
392+
resetState: (timeout: number) => void
393+
} {
394+
const [state, setState] = useState(initialState)
395+
const [prevState, setPrevState] = useState(initialState)
396+
const prevReadyTimeoutRef = useRef<number | null>(null)
397+
398+
const setStateAndClearResets = useCallback(
399+
(value: boolean) => {
400+
setState(value)
401+
402+
if (value) {
403+
setPrevState(true)
404+
if (prevReadyTimeoutRef.current !== null) {
405+
window.clearTimeout(prevReadyTimeoutRef.current)
406+
prevReadyTimeoutRef.current = null
407+
}
408+
}
409+
},
410+
[setState, setPrevState]
411+
)
412+
413+
const resetStateAfterDelay = useCallback((timeout: number) => {
414+
if (prevReadyTimeoutRef.current !== null) {
415+
window.clearTimeout(prevReadyTimeoutRef.current)
416+
}
417+
prevReadyTimeoutRef.current = window.setTimeout(() => {
418+
prevReadyTimeoutRef.current = null
419+
setPrevState(false)
420+
}, timeout)
421+
}, [])
422+
423+
return {
424+
state: state || prevState,
425+
setState: setStateAndClearResets,
426+
resetState: resetStateAfterDelay,
427+
}
428+
}
429+
373430
/**
374431
* A Meteor Subscription hook that allows using React Functional Components and the Hooks API with Meteor subscriptions.
375432
* Subscriptions will be torn down 1000ms after unmounting the component.
@@ -383,20 +440,28 @@ export function useSubscription<K extends keyof AllPubSubTypes>(
383440
sub: K,
384441
...args: Parameters<AllPubSubTypes[K]>
385442
): boolean {
386-
const [ready, setReady] = useState<boolean>(false)
443+
const { state: ready, setState: setReady, resetState: cancelPreviousReady } = useDelayState()
387444

388445
useEffect(() => {
389446
const subscription = Tracker.nonreactive(() => meteorSubscribe(sub, ...args))
390-
const isReadyComp = Tracker.nonreactive(() => Tracker.autorun(() => setReady(subscription.ready())))
447+
const isReadyComp = Tracker.nonreactive(() =>
448+
Tracker.autorun(() => {
449+
const isNowReady = subscription.ready()
450+
setReady(isNowReady)
451+
})
452+
)
391453
return () => {
392454
isReadyComp.stop()
393455
setTimeout(() => {
394456
subscription.stop()
395-
}, 1000)
457+
}, SUBSCRIPTION_TIMEOUT)
458+
cancelPreviousReady(SUBSCRIPTION_TIMEOUT)
396459
}
397460
}, [sub, stringifyObjects(args)])
398461

399-
return ready
462+
const isReady = ready
463+
464+
return isReady
400465
}
401466

402467
/**
@@ -415,7 +480,7 @@ export function useSubscriptionIfEnabled<K extends keyof AllPubSubTypes>(
415480
enable: boolean,
416481
...args: Parameters<AllPubSubTypes[K]>
417482
): boolean {
418-
const [ready, setReady] = useState<boolean>(false)
483+
const { state: ready, setState: setReady, resetState: cancelPreviousReady } = useDelayState()
419484

420485
useEffect(() => {
421486
if (!enable) {
@@ -424,16 +489,69 @@ export function useSubscriptionIfEnabled<K extends keyof AllPubSubTypes>(
424489
}
425490

426491
const subscription = Tracker.nonreactive(() => meteorSubscribe(sub, ...args))
427-
const isReadyComp = Tracker.nonreactive(() => Tracker.autorun(() => setReady(subscription.ready())))
492+
const isReadyComp = Tracker.nonreactive(() =>
493+
Tracker.autorun(() => {
494+
const isNowReady = subscription.ready()
495+
setReady(isNowReady)
496+
})
497+
)
428498
return () => {
429499
isReadyComp.stop()
430500
setTimeout(() => {
431501
subscription.stop()
432-
}, 1000)
502+
}, SUBSCRIPTION_TIMEOUT)
503+
cancelPreviousReady(SUBSCRIPTION_TIMEOUT)
433504
}
434505
}, [sub, enable, stringifyObjects(args)])
435506

436-
return !enable || ready
507+
const isReady = !enable || ready
508+
509+
return isReady
510+
}
511+
512+
/**
513+
* A Meteor Subscription hook that allows using React Functional Components and the Hooks API with Meteor subscriptions.
514+
* Subscriptions will be torn down 1000ms after unmounting the component.
515+
* If the subscription is not enabled, the subscription will not be created, and the ready state will always be true.
516+
*
517+
* @export
518+
* @param {PubSub} sub The subscription to be subscribed to
519+
* @param {boolean} enable Whether the subscription is enabled
520+
* @param {...any[]} args A list of arugments for the subscription. This is used for optimizing the subscription across
521+
* renders so that it isn't torn down and created for every render.
522+
*/
523+
export function useSubscriptionIfEnabledReadyOnce<K extends keyof AllPubSubTypes>(
524+
sub: K,
525+
enable: boolean,
526+
...args: Parameters<AllPubSubTypes[K]>
527+
): boolean {
528+
const { state: ready, setState: setReady, resetState: cancelPreviousReady } = useDelayState()
529+
530+
useEffect(() => {
531+
if (!enable) {
532+
setReady(false)
533+
return
534+
}
535+
536+
const subscription = Tracker.nonreactive(() => meteorSubscribe(sub, ...args))
537+
const isReadyComp = Tracker.nonreactive(() =>
538+
Tracker.autorun(() => {
539+
const isNowReady = subscription.ready()
540+
if (isNowReady) setReady(true)
541+
})
542+
)
543+
return () => {
544+
isReadyComp.stop()
545+
setTimeout(() => {
546+
subscription.stop()
547+
}, SUBSCRIPTION_TIMEOUT)
548+
cancelPreviousReady(SUBSCRIPTION_TIMEOUT)
549+
}
550+
}, [sub, enable, stringifyObjects(args)])
551+
552+
const isReady = !enable || ready
553+
554+
return isReady
437555
}
438556

439557
/**

0 commit comments

Comments
 (0)