Merge pull request 'fix(7.22): clear the makedata poll on destroy, and close the release-gate findings' (#477) from fix/7.22-release-followups into release/7.22
Reviewed-on: #477
This commit was merged in pull request #477.
This commit is contained in:
commit
eef91ce989
7 files changed
+73
-25
No files matched your search
@@ -190,13 +190,15 @@ jobs:
|
||||
key: angular-v1-${{ github.base_ref }}-${{ hashFiles('client/package-lock.json') }}
|
||||
|
||||
- name: Check audit
|
||||
# Audit should fail and stop the CI on any vulnerability in root and sas, and on low+ in client
|
||||
# Root and sas fail on moderate and above (npm's default), client on
|
||||
# low and above - the flags below are what makes that true, so they have
|
||||
# to stay in step with this comment.
|
||||
run: |
|
||||
npm audit --omit=dev
|
||||
cd ./sas
|
||||
npm audit --omit=dev
|
||||
cd ../client
|
||||
npm audit --omit=dev
|
||||
npm audit --omit=dev --audit-level=low
|
||||
|
||||
- name: Check archiver directory walk
|
||||
# the readdir-glob minimatch override in client/package.json is a major
|
||||
|
||||
@@ -50,19 +50,21 @@ jobs:
|
||||
fi
|
||||
|
||||
# .gitea/scripts/ carries the runner-memory gate this job runs before
|
||||
# it starts, so a change there has to be exercised too.
|
||||
if printf '%s\n' "$CHANGED" | grep -qE '^(client/|sas/mocks/|\.gitea/scripts/|package-lock\.json|\.gitea/workflows/lighthouse\.yaml)'; then
|
||||
# it starts, so a change there has to be exercised too. sas/package.json
|
||||
# is what this job reads for the @sasjs/cli pin below, so a bump there
|
||||
# has to be audited as well - build.yaml's matcher covers it too.
|
||||
if printf '%s\n' "$CHANGED" | grep -qE '^(client/|sas/mocks/|sas/package\.json|\.gitea/scripts/|package-lock\.json|\.gitea/workflows/lighthouse\.yaml)'; then
|
||||
echo "client=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "client=false" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice::Lighthouse audit skipped - nothing under client/, sas/mocks/ or .gitea/scripts/ changed"
|
||||
echo "::notice::Lighthouse audit skipped - nothing under client/, sas/mocks/, sas/package.json or .gitea/scripts/ changed"
|
||||
printf 'Skipping the audit - nothing it reads changed:\n%s\n' "$CHANGED"
|
||||
fi
|
||||
|
||||
- name: Lighthouse audit not run - no client changes
|
||||
if: steps.changes.outputs.client == 'false'
|
||||
run: |
|
||||
echo "No client, sas/mocks or .gitea/scripts change in this pull request - the audit was skipped by design."
|
||||
echo "No client, sas/mocks, sas/package.json or .gitea/scripts change in this pull request - the audit was skipped by design."
|
||||
echo "The detection step above lists the files it saw, and warns instead if it could not decide (in which case the audit runs)."
|
||||
|
||||
- name: Check runner size
|
||||
|
||||
@@ -99,7 +99,10 @@ jobs:
|
||||
# client install scripts are off (client/.npmrc); the generator that
|
||||
# creates src/environments/version.ts runs explicitly
|
||||
npm run postinstall
|
||||
npm i webpack
|
||||
# webpack comes from the client lockfile, so install the version it
|
||||
# already resolves rather than whatever is current at release time
|
||||
WEBPACK_VERSION=$(node -p "require('./package-lock.json').packages['node_modules/webpack'].version")
|
||||
npm i --no-save "webpack@${WEBPACK_VERSION}"
|
||||
npm run build
|
||||
shell: bash
|
||||
env:
|
||||
|
||||
@@ -156,6 +156,10 @@ describe('AutomaticComponent (Viya setup)', () => {
|
||||
opened.push(String(url))
|
||||
return null
|
||||
})
|
||||
// The real poll loads the page once it sees makedata finish: left running
|
||||
// here it fires five seconds later, during whichever spec is running then,
|
||||
// and Karma aborts with "Some of your tests did a full page reload".
|
||||
spyOn(component as any, 'pollMakedataCompletion')
|
||||
|
||||
component.runMakedataInNewWindow({
|
||||
contextName: 'SAS Job Execution & co',
|
||||
@@ -170,6 +174,25 @@ describe('AutomaticComponent (Viya setup)', () => {
|
||||
expect(opened[0]).toContain('&admin=group%201%2B2')
|
||||
})
|
||||
|
||||
it('stops the makedata poll when the screen is destroyed', () => {
|
||||
// The poll runs every five seconds for up to ten minutes and reloads the
|
||||
// page the first time it sees makedata gone. It must not outlive the
|
||||
// screen: a timer left behind reloads whatever the user moved on to.
|
||||
const { component } = build()
|
||||
spyOn(window, 'open')
|
||||
|
||||
component.runMakedataInNewWindow({
|
||||
contextName: 'Compute Reusable',
|
||||
admin: 'viyagroup18',
|
||||
dcPath: '/export/dc'
|
||||
})
|
||||
expect((component as any).makedataPollInterval).not.toBeNull()
|
||||
|
||||
component.ngOnDestroy()
|
||||
|
||||
expect((component as any).makedataPollInterval).toBeNull()
|
||||
})
|
||||
|
||||
it('starts the job when deploy is pressed', () => {
|
||||
// The screen's only button calls this; a version where it stopped doing so
|
||||
// would leave the setup page unable to do anything at all.
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewEncapsulation
|
||||
@@ -39,7 +40,7 @@ export interface ComputeContextInfo {
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
standalone: false
|
||||
})
|
||||
export class AutomaticComponent implements OnInit {
|
||||
export class AutomaticComponent implements OnInit, OnDestroy {
|
||||
@Input() sasJs!: SASjs
|
||||
@Input() sasJsConfig: SASjsConfig = new SASjsConfig()
|
||||
@Input() dcAdapterSettings: DcAdapterSettings | undefined
|
||||
@@ -564,10 +565,25 @@ export class AutomaticComponent implements OnInit {
|
||||
|
||||
private makedataPollInterval: any = null
|
||||
|
||||
private pollMakedataCompletion() {
|
||||
/**
|
||||
* The poll outlives the deploy screen if the user navigates away, and it
|
||||
* loads the page again the moment it sees makedata finish. Stop it with the
|
||||
* component, so a timer cannot reload the page from under whatever the user
|
||||
* moved on to.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.stopMakedataPoll()
|
||||
}
|
||||
|
||||
private stopMakedataPoll(): void {
|
||||
if (this.makedataPollInterval) {
|
||||
clearInterval(this.makedataPollInterval)
|
||||
this.makedataPollInterval = null
|
||||
}
|
||||
}
|
||||
|
||||
private pollMakedataCompletion() {
|
||||
this.stopMakedataPoll()
|
||||
|
||||
let attempts = 0
|
||||
const maxAttempts = 120 // 10 minutes at 5s intervals
|
||||
@@ -584,8 +600,7 @@ export class AutomaticComponent implements OnInit {
|
||||
console.log(
|
||||
'pollMakedataCompletion: makedata job is gone, reloading app'
|
||||
)
|
||||
clearInterval(this.makedataPollInterval)
|
||||
this.makedataPollInterval = null
|
||||
this.stopMakedataPoll()
|
||||
|
||||
// Reload the app fresh from the SASJobExecution URL
|
||||
window.location.href = window.location.href.split('#')[0]
|
||||
@@ -598,8 +613,7 @@ export class AutomaticComponent implements OnInit {
|
||||
console.warn(
|
||||
'pollMakedataCompletion: timed out after 10 minutes, stopping poll'
|
||||
)
|
||||
clearInterval(this.makedataPollInterval)
|
||||
this.makedataPollInterval = null
|
||||
this.stopMakedataPoll()
|
||||
}
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
|
||||
/*
|
||||
These macros write their JSON answer to _webout. Point it at a temporary
|
||||
file while they run and put it back afterwards, so the test's own result -
|
||||
which the term program writes to _webout - still reaches the caller. The
|
||||
assertions read the work datasets the macros build, not the JSON.
|
||||
file while they run; the term program's %webout(OPEN) assigns _webout again
|
||||
before it dumps the results, so the test's own result still reaches the
|
||||
caller. The assertions read the work datasets the macros build, not the
|
||||
JSON.
|
||||
*/
|
||||
%let _webout_path=%sysfunc(pathname(_webout));
|
||||
filename _webout temp;
|
||||
|
||||
%let root=%sysfunc(pathname(work))/dirlist%mf_getuniquefileref();
|
||||
@@ -169,9 +169,11 @@ run;
|
||||
)
|
||||
|
||||
/*
|
||||
hand _webout back before the results are dumped
|
||||
Nothing to hand back: on JES _webout is a filesrvc fileref whose pathname()
|
||||
is empty, so restoring it by path fails with "Invalid physical name" and
|
||||
leaves the temporary file in place. The term program's %webout(OPEN)
|
||||
assigns _webout itself before it dumps the results.
|
||||
*/
|
||||
filename _webout "&_webout_path" mod;
|
||||
|
||||
/**
|
||||
* dump results to the log for offline inspection
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
|
||||
/*
|
||||
These macros write their JSON answer to _webout. Point it at a temporary
|
||||
file while they run and put it back afterwards, so the test's own result -
|
||||
which the term program writes to _webout - still reaches the caller. The
|
||||
assertions read the work datasets the macros build, not the JSON.
|
||||
file while they run; the term program's %webout(OPEN) assigns _webout again
|
||||
before it dumps the results, so the test's own result still reaches the
|
||||
caller. The assertions read the work datasets the macros build, not the
|
||||
JSON.
|
||||
*/
|
||||
%let _webout_path=%sysfunc(pathname(_webout));
|
||||
filename _webout temp;
|
||||
|
||||
%let root=%sysfunc(pathname(work))/checkwrite%mf_getuniquefileref();
|
||||
@@ -125,9 +125,11 @@ run;
|
||||
)
|
||||
|
||||
/*
|
||||
hand _webout back before the results are dumped
|
||||
Nothing to hand back: on JES _webout is a filesrvc fileref whose pathname()
|
||||
is empty, so restoring it by path fails with "Invalid physical name" and
|
||||
leaves the temporary file in place. The term program's %webout(OPEN)
|
||||
assigns _webout itself before it dumps the results.
|
||||
*/
|
||||
filename _webout "&_webout_path" mod;
|
||||
|
||||
/**
|
||||
* dump results to the log for offline inspection
|
||||
|
||||
Reference in new issue
Block a user