@omega.js/desktop 0.51.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -13
- package/dist/assets/css/core/_initialize.scss +1 -1
- package/dist/assets/js/core/app-shell.js +14 -15
- package/dist/assets/themes/_template/_theme.js +6 -6
- package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
- package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
- package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
- package/dist/assets/themes/base/_theme.js +4 -3
- package/dist/assets/themes/bootstrap/_theme.js +2 -2
- package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
- package/dist/assets/themes/classy/_theme.js +8 -6
- package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
- package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
- package/dist/assets/themes/neobrutalism/_theme.js +5 -5
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/assets/themes/newsflash/_theme.js +6 -6
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/build.js +87 -111
- package/dist/cli.js +1 -1
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- package/dist/commands/cdp/quit.js +2 -2
- package/dist/commands/cdp/relaunch.js +2 -2
- package/dist/commands/cdp/theme.js +1 -1
- package/dist/commands/clean.js +2 -2
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/install.js +3 -3
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +6 -6
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +3 -3
- package/dist/commands/runner.js +145 -48
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +4 -4
- package/dist/commands/update.js +2 -2
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/.github/workflows/build.yml +2 -0
- package/dist/defaults/AGENTS.md +17 -8
- package/dist/defaults/config/omega.json5 +7 -7
- package/dist/defaults/hooks/build/post.js +1 -1
- package/dist/defaults/hooks/build/pre.js +1 -1
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/release/post.js +1 -1
- package/dist/defaults/hooks/release/pre.js +1 -1
- package/dist/defaults/src/assets/js/components/about/index.js +3 -5
- package/dist/defaults/src/assets/js/components/main/index.js +3 -5
- package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
- package/dist/defaults/src/integrations/context-menu/index.js +2 -2
- package/dist/defaults/src/integrations/menu/index.js +3 -3
- package/dist/defaults/src/integrations/tray/index.js +3 -3
- package/dist/defaults/src/main.js +3 -5
- package/dist/defaults/src/preload.js +3 -5
- package/dist/defaults/test/README.md +2 -2
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +7 -7
- package/dist/gulp/tasks/build-config.js +8 -8
- package/dist/gulp/tasks/bundle.js +16 -16
- package/dist/gulp/tasks/defaults.js +3 -3
- package/dist/gulp/tasks/distribute.js +2 -2
- package/dist/gulp/tasks/html.js +9 -9
- package/dist/gulp/tasks/package-quick.js +3 -3
- package/dist/gulp/tasks/package.js +3 -3
- package/dist/gulp/tasks/release.js +3 -3
- package/dist/gulp/tasks/sass.js +6 -6
- package/dist/gulp/tasks/serve.js +4 -4
- package/dist/hooks/notarize-artifacts.js +1 -1
- package/dist/hooks/notarize.js +1 -1
- package/dist/index.js +5 -8
- package/dist/lib/_environment-mixin.js +50 -0
- package/dist/lib/_lifecycle-mixin.js +45 -0
- package/dist/lib/analytics.js +33 -35
- package/dist/lib/app-state.js +14 -14
- package/dist/lib/auth-flow.js +18 -18
- package/dist/lib/auth-persistence.js +12 -12
- package/dist/lib/auth.js +421 -0
- package/dist/lib/auto-updater.js +49 -49
- package/dist/lib/context-menu.js +13 -13
- package/dist/lib/context.js +19 -19
- package/dist/lib/deep-link.js +34 -34
- package/dist/lib/fontawesome.js +5 -5
- package/dist/lib/ipc.js +4 -4
- package/dist/lib/menu.js +25 -25
- package/dist/lib/protocol.js +5 -5
- package/dist/lib/remote-config.js +22 -22
- package/dist/lib/remote-scripts.js +21 -21
- package/dist/lib/restart-manager/index.js +28 -28
- package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
- package/dist/lib/sign-helpers/sign-events.js +1 -1
- package/dist/lib/startup.js +18 -13
- package/dist/lib/storage.js +10 -10
- package/dist/lib/templating.js +16 -16
- package/dist/lib/theme.js +10 -10
- package/dist/lib/tray.js +27 -27
- package/dist/lib/usage.js +11 -11
- package/dist/lib/window-manager.js +26 -26
- package/dist/main.js +398 -483
- package/dist/preload.js +236 -176
- package/dist/renderer.js +417 -391
- package/dist/runner/job-started.js +1 -1
- package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
- package/dist/test/fixtures/consumer-app/src/main.js +5 -7
- package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
- package/dist/test/harness/boot-entry.js +22 -20
- package/dist/test/harness/main-entry.js +31 -30
- package/dist/test/harness/renderer-entry.js +5 -5
- package/dist/test/harness/renderer-preload.js +137 -141
- package/dist/test/index.js +10 -10
- package/dist/test/runner.js +2 -2
- package/dist/test/runners/boot.js +7 -6
- package/dist/test/runners/electron.js +3 -2
- package/dist/test/runners/render-event.js +2 -2
- package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
- package/dist/test/suites/boot/restart-manager.test.js +2 -2
- package/dist/test/suites/boot/storage-bundled.test.js +5 -5
- package/dist/test/suites/boot/theme.test.js +13 -13
- package/dist/test/suites/build/audit.test.js +1 -1
- package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
- package/dist/test/suites/build/boot-fixture.test.js +2 -2
- package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
- package/dist/test/suites/build/brand-scss.test.js +1 -1
- package/dist/test/suites/build/build-json-bake.test.js +1 -1
- package/dist/test/suites/build/cli.test.js +2 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-scaffold.test.js +2 -2
- package/dist/test/suites/build/deploy-hook.test.js +3 -3
- package/dist/test/suites/build/ensure-target.test.js +2 -2
- package/dist/test/suites/build/env-delivery.test.js +2 -2
- package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
- package/dist/test/suites/build/exports.test.js +9 -8
- package/dist/test/suites/build/get-config.test.js +4 -4
- package/dist/test/suites/build/manifest-deps.test.js +1 -1
- package/dist/test/suites/build/merge-line-files.test.js +1 -1
- package/dist/test/suites/build/omega-shell.test.js +34 -2
- package/dist/test/suites/build/omega.test.js +350 -0
- package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner.test.js +612 -5
- package/dist/test/suites/build/sentry.test.js +2 -2
- package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
- package/dist/test/suites/build/templating.test.js +3 -3
- package/dist/test/suites/build/test-stealth.test.js +7 -9
- package/dist/test/suites/build/url-helpers.test.js +55 -56
- package/dist/test/suites/build/validate-config.test.js +2 -2
- package/dist/test/suites/build/wave5-pins.test.js +2 -2
- package/dist/test/suites/main/analytics.test.js +59 -59
- package/dist/test/suites/main/app-state.test.js +66 -66
- package/dist/test/suites/main/auth-flow.test.js +41 -41
- package/dist/test/suites/main/auth-persistence.test.js +54 -43
- package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
- package/dist/test/suites/main/auth.test.js +336 -0
- package/dist/test/suites/main/auto-updater.test.js +134 -134
- package/dist/test/suites/main/boot-sequence.test.js +37 -49
- package/dist/test/suites/main/context-menu.test.js +51 -50
- package/dist/test/suites/main/context.test.js +25 -25
- package/dist/test/suites/main/deep-link.test.js +74 -74
- package/dist/test/suites/main/fontawesome.test.js +27 -27
- package/dist/test/suites/main/ipc.test.js +35 -35
- package/dist/test/suites/main/menu.test.js +101 -100
- package/dist/test/suites/main/protocol.test.js +19 -19
- package/dist/test/suites/main/remote-config.test.js +63 -63
- package/dist/test/suites/main/remote-scripts.test.js +103 -103
- package/dist/test/suites/main/request.test.js +71 -0
- package/dist/test/suites/main/restart-manager.test.js +33 -33
- package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
- package/dist/test/suites/main/startup.test.js +26 -26
- package/dist/test/suites/main/stealth-window.test.js +1 -1
- package/dist/test/suites/main/storage.test.js +25 -25
- package/dist/test/suites/main/theme.test.js +34 -34
- package/dist/test/suites/main/tray.test.js +79 -79
- package/dist/test/suites/main/url-helpers.test.js +133 -133
- package/dist/test/suites/main/usage.test.js +25 -25
- package/dist/test/suites/main/window-bounds.test.js +27 -27
- package/dist/test/suites/main/window-manager.test.js +44 -44
- package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
- package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
- package/dist/test/suites/renderer/round-trip.test.js +3 -3
- package/dist/test/suites/renderer/tooltips.test.js +15 -15
- package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +27 -7
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/mode-helpers.js +2 -15
- package/dist/utils/ship-keys.js +3 -3
- package/dist/utils/signing-status.js +51 -0
- package/dist/utils/test-events.js +7 -0
- package/dist/utils/test-stealth.js +6 -6
- package/dist/utils/url-helpers.js +52 -42
- package/dist/utils/user-agent.js +44 -0
- package/dist/vendor/account/engine.js +3 -3
- package/dist/vendor/account/index.js +14 -45
- package/dist/vendor/account/resolve-account.js +44 -0
- package/dist/vendor/account/schema.js +1 -1
- package/dist/vendor/account/user.js +99 -0
- package/dist/vendor/config/client-config.js +1 -1
- package/dist/vendor/config/environment.js +11 -30
- package/dist/vendor/config/index.js +13 -12
- package/dist/vendor/config/load.js +1 -2
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/repo.js +24 -0
- package/dist/vendor/config/retired-keys.js +2 -2
- package/dist/vendor/config/schema.js +5 -8
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +1 -2
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/attach-log-file.js +1 -1
- package/dist/vendor/devkit/brand-version.js +162 -1
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/cli-router.js +3 -4
- package/dist/vendor/devkit/defaults-engine.js +9 -11
- package/dist/vendor/devkit/deploy.js +64 -4
- package/dist/vendor/devkit/git-remote.js +78 -1
- package/dist/vendor/devkit/local.js +53 -3
- package/dist/vendor/devkit/lockfile.js +127 -0
- package/dist/vendor/devkit/merge-line-files.js +2 -3
- package/dist/vendor/devkit/pack-local.js +4 -7
- package/dist/vendor/devkit/preludes/origin-heal.js +35 -49
- package/dist/vendor/devkit/target-secrets.js +34 -45
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- package/dist/vendor/monitoring/env.js +2 -2
- package/dist/vendor/monitoring/index.js +1 -1
- package/dist/vendor/monitoring/main.js +1 -1
- package/dist/vendor/monitoring/preload.js +1 -1
- package/dist/vendor/monitoring/renderer.js +1 -1
- package/docs/analytics.md +8 -8
- package/docs/app-state.md +19 -19
- package/docs/audit.md +4 -4
- package/docs/{client-bridge.md → auth.md} +88 -73
- package/docs/auto-updater.md +8 -8
- package/docs/boot-sequence.md +11 -6
- package/docs/build-system.md +1 -1
- package/docs/cdp-debugging.md +1 -1
- package/docs/common-mistakes.md +7 -7
- package/docs/config-schema.md +1 -1
- package/docs/context-menu.md +13 -13
- package/docs/context.md +11 -11
- package/docs/css.md +3 -9
- package/docs/deep-link.md +25 -25
- package/docs/environment-detection.md +16 -16
- package/docs/fontawesome.md +7 -5
- package/docs/hooks.md +8 -8
- package/docs/index.md +39 -28
- package/docs/ipc.md +10 -10
- package/docs/lib-modules.md +9 -9
- package/docs/logging.md +12 -14
- package/docs/menu.md +18 -18
- package/docs/releasing.md +4 -2
- package/docs/remote-config.md +9 -9
- package/docs/remote-scripts.md +12 -12
- package/docs/restart-manager.md +8 -8
- package/docs/runner.md +12 -10
- package/docs/sentry.md +4 -4
- package/docs/shared/analytics.md +1 -1
- package/docs/shared/brands.md +1 -1
- package/docs/shared/breaking-changes.md +79 -13
- package/docs/shared/config.md +24 -21
- package/docs/shared/deploys.md +30 -7
- package/docs/shared/local-dev.md +5 -3
- package/docs/shared/logging.md +1 -1
- package/docs/shared/monitoring.md +5 -5
- package/docs/shared/testing.md +2 -2
- package/docs/shared/theming.md +1 -1
- package/docs/shared/translation.md +19 -10
- package/docs/signing.md +1 -1
- package/docs/startup.md +16 -16
- package/docs/storage.md +11 -11
- package/docs/templating.md +3 -3
- package/docs/test-boot-layer.md +12 -12
- package/docs/test-framework.md +17 -17
- package/docs/themes.md +7 -7
- package/docs/tooltips.md +2 -2
- package/docs/tray.md +31 -31
- package/docs/usage.md +7 -7
- package/docs/verts.md +1 -1
- package/docs/windows.md +22 -22
- package/package.json +3 -4
- package/dist/lib/client-bridge.js +0 -374
- package/dist/lib/logger.js +0 -4
- package/dist/test/suites/build/manager.test.js +0 -213
- package/dist/test/suites/main/client-bridge.test.js +0 -262
|
@@ -78,8 +78,8 @@ module.exports = defineCases({
|
|
|
78
78
|
jetpack.remove(realish); // a RED run of this case is what would create it
|
|
79
79
|
try {
|
|
80
80
|
// Every verb that CHANGES the machine — stop kills real listeners under
|
|
81
|
-
// the home
|
|
82
|
-
for (const sub of ['install', 'config', 'register-org', 'start', 'restart', 'stop', 'uninstall'
|
|
81
|
+
// the home.
|
|
82
|
+
for (const sub of ['install', 'config', 'register-org', 'start', 'restart', 'stop', 'uninstall']) {
|
|
83
83
|
let threw;
|
|
84
84
|
try {
|
|
85
85
|
// `_env: {}` is a fixture for the config walk. It is NOT an answer
|
|
@@ -565,7 +565,7 @@ module.exports = defineCases({
|
|
|
565
565
|
const src = fs.readFileSync(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'), 'utf8');
|
|
566
566
|
ctx.expect(src).toContain('Existing runner installation detected');
|
|
567
567
|
ctx.expect(src).toContain('uninstalling first for a clean re-install');
|
|
568
|
-
// ...and the
|
|
568
|
+
// ...and the legacy em-runner install counts as an existing one.
|
|
569
569
|
ctx.expect(src).toMatch(/jetpack\.exists\(home\)\s*\|\|\s*listLegacyRunnerHomes\(\{ home \}\)\.length > 0/);
|
|
570
570
|
},
|
|
571
571
|
},
|
|
@@ -1013,7 +1013,7 @@ module.exports = defineCases({
|
|
|
1013
1013
|
},
|
|
1014
1014
|
},
|
|
1015
1015
|
{
|
|
1016
|
-
name: 'the
|
|
1016
|
+
name: 'the legacy em-runner homes are found from the environment, never the current home',
|
|
1017
1017
|
run: (ctx) => {
|
|
1018
1018
|
// An upgraded box still runs `em runner`'s install out of
|
|
1019
1019
|
// %LOCALAPPDATA%\em-runner (C:\actions-runners before that). Those are
|
|
@@ -1720,6 +1720,9 @@ module.exports = defineCases({
|
|
|
1720
1720
|
const logged = [];
|
|
1721
1721
|
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
1722
1722
|
try {
|
|
1723
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
1724
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
1725
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
1723
1726
|
let threw;
|
|
1724
1727
|
try {
|
|
1725
1728
|
await runner({ _: ['runner', 'start'], _home: home, _env: {}, _logger: logger, _prompt: {}, _interactive: false });
|
|
@@ -1814,6 +1817,9 @@ module.exports = defineCases({
|
|
|
1814
1817
|
const spawned = [];
|
|
1815
1818
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
1816
1819
|
try {
|
|
1820
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
1821
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
1822
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
1817
1823
|
for (const org of orgs) jetpack.dir(path.join(home, `actions-runner-${org}`));
|
|
1818
1824
|
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
1819
1825
|
|
|
@@ -1863,6 +1869,9 @@ module.exports = defineCases({
|
|
|
1863
1869
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
1864
1870
|
const aliveDir = path.join(home, 'actions-runner-acme');
|
|
1865
1871
|
try {
|
|
1872
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
1873
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
1874
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
1866
1875
|
for (const org of orgs) jetpack.dir(path.join(home, `actions-runner-${org}`));
|
|
1867
1876
|
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
1868
1877
|
|
|
@@ -1907,6 +1916,9 @@ module.exports = defineCases({
|
|
|
1907
1916
|
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
1908
1917
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
1909
1918
|
try {
|
|
1919
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
1920
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
1921
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
1910
1922
|
for (const org of orgs) jetpack.dir(path.join(home, `actions-runner-${org}`));
|
|
1911
1923
|
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
1912
1924
|
|
|
@@ -1949,6 +1961,9 @@ module.exports = defineCases({
|
|
|
1949
1961
|
const spawned = [];
|
|
1950
1962
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
1951
1963
|
try {
|
|
1964
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
1965
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
1966
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
1952
1967
|
jetpack.dir(path.join(home, 'actions-runner-acme'));
|
|
1953
1968
|
jetpack.write(shortcut, '@echo off\r\n');
|
|
1954
1969
|
|
|
@@ -2043,6 +2058,9 @@ module.exports = defineCases({
|
|
|
2043
2058
|
const waits = [];
|
|
2044
2059
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2045
2060
|
try {
|
|
2061
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
2062
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
2063
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
2046
2064
|
jetpack.dir(path.join(home, 'actions-runner-acme'));
|
|
2047
2065
|
jetpack.write(shortcut, '@echo off\r\n');
|
|
2048
2066
|
|
|
@@ -2092,6 +2110,9 @@ module.exports = defineCases({
|
|
|
2092
2110
|
const waits = [];
|
|
2093
2111
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2094
2112
|
try {
|
|
2113
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
2114
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
2115
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
2095
2116
|
jetpack.dir(path.join(home, 'actions-runner-acme'));
|
|
2096
2117
|
jetpack.write(shortcut, '@echo off\r\n');
|
|
2097
2118
|
|
|
@@ -2130,7 +2151,7 @@ module.exports = defineCases({
|
|
|
2130
2151
|
ctx.expect(startSrc.includes("stdio: 'inherit'")).toBe(false);
|
|
2131
2152
|
ctx.expect(startSrc.includes('spawnSync')).toBe(false);
|
|
2132
2153
|
// ...and install hands off to it rather than foregrounding one org.
|
|
2133
|
-
ctx.expect(src).toContain('await startServices({ ...options, _home: home })');
|
|
2154
|
+
ctx.expect(src).toContain('await startServices({ ...options, _home: home, _reconcileDone: true })');
|
|
2134
2155
|
|
|
2135
2156
|
// The spawn's own options, pinned the same way: the listener is handed
|
|
2136
2157
|
// the runner's private HOME ([#807](https://github.com/Omega-JS-Stack/omega/issues/807))
|
|
@@ -2166,6 +2187,9 @@ module.exports = defineCases({
|
|
|
2166
2187
|
const spawned = [];
|
|
2167
2188
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2168
2189
|
try {
|
|
2190
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
2191
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
2192
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
2169
2193
|
for (const org of orgs) jetpack.dir(path.join(home, `actions-runner-${org}`));
|
|
2170
2194
|
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
2171
2195
|
|
|
@@ -2218,6 +2242,9 @@ module.exports = defineCases({
|
|
|
2218
2242
|
const spawned = [];
|
|
2219
2243
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2220
2244
|
try {
|
|
2245
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
2246
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
2247
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
2221
2248
|
jetpack.dir(path.join(home, 'actions-runner-acme'));
|
|
2222
2249
|
jetpack.write(shortcut, '@echo off\r\n');
|
|
2223
2250
|
|
|
@@ -2585,6 +2612,9 @@ module.exports = defineCases({
|
|
|
2585
2612
|
const logger = { log: (m) => logged.push(String(m)), warn: (m) => logged.push(String(m)), error: (m) => logged.push(String(m)) };
|
|
2586
2613
|
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2587
2614
|
try {
|
|
2615
|
+
// Installed and current, so `start` goes straight to its spawns (#937).
|
|
2616
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), '@echo off\r\n');
|
|
2617
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION });
|
|
2588
2618
|
for (const org of orgs) jetpack.write(path.join(home, `actions-runner-${org}`, 'config.cmd'), '@echo off\r\n');
|
|
2589
2619
|
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
2590
2620
|
ctx.expect(jetpack.exists(path.join(home, 'home'))).toBe(false);
|
|
@@ -2618,5 +2648,582 @@ module.exports = defineCases({
|
|
|
2618
2648
|
}
|
|
2619
2649
|
},
|
|
2620
2650
|
},
|
|
2651
|
+
{
|
|
2652
|
+
name: '`start` on a bare box installs: a home with no `_template/config.cmd` hands the whole run to install, once',
|
|
2653
|
+
run: async (ctx) => {
|
|
2654
|
+
// `start` is the one command (#937). A box with nothing installed gets
|
|
2655
|
+
// the install, which itself ends by bringing every org online, so
|
|
2656
|
+
// nothing else of `start` runs: no config walk of its own, no refresh,
|
|
2657
|
+
// no org check, no spawn.
|
|
2658
|
+
const fs = require('fs');
|
|
2659
|
+
const os = require('os');
|
|
2660
|
+
const jetpack = require('fs-jetpack');
|
|
2661
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
2662
|
+
|
|
2663
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
2664
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
2665
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
2666
|
+
const logged = [];
|
|
2667
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
2668
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2669
|
+
const installs = [];
|
|
2670
|
+
const spawned = [];
|
|
2671
|
+
let downloads = 0;
|
|
2672
|
+
let discovers = 0;
|
|
2673
|
+
let registers = 0;
|
|
2674
|
+
try {
|
|
2675
|
+
const options = {
|
|
2676
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
2677
|
+
_listeners: () => [],
|
|
2678
|
+
_spawn: (dir) => { spawned.push(dir); return { ok: true, pid: 1 }; },
|
|
2679
|
+
_install: async (o) => { installs.push(o); },
|
|
2680
|
+
_download: async () => { downloads++; },
|
|
2681
|
+
_discoverOrgs: async () => { discovers++; return []; },
|
|
2682
|
+
_registerOrg: async () => { registers++; },
|
|
2683
|
+
};
|
|
2684
|
+
await runner(options);
|
|
2685
|
+
|
|
2686
|
+
ctx.expect(installs.length).toBe(1);
|
|
2687
|
+
ctx.expect(installs[0]).toBe(options); // the same options, untouched
|
|
2688
|
+
ctx.expect(spawned).toEqual([]);
|
|
2689
|
+
ctx.expect(downloads).toBe(0);
|
|
2690
|
+
ctx.expect(discovers).toBe(0);
|
|
2691
|
+
ctx.expect(registers).toBe(0);
|
|
2692
|
+
ctx.expect(jetpack.exists(path.join(home, '.env'))).toBe(false); // start's own config walk never ran
|
|
2693
|
+
} finally {
|
|
2694
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
2695
|
+
jetpack.remove(home);
|
|
2696
|
+
}
|
|
2697
|
+
},
|
|
2698
|
+
},
|
|
2699
|
+
{
|
|
2700
|
+
name: '`start` refreshes a stale actions/runner in place: the template is re-downloaded and copied over each stopped org, its registration kept',
|
|
2701
|
+
run: async (ctx) => {
|
|
2702
|
+
// A bumped ACTIONS_RUNNER_VERSION used to mean `install`, which tears
|
|
2703
|
+
// the box down. The template is re-downloaded and laid over each org dir
|
|
2704
|
+
// instead; `.runner`, `.credentials` and `.env` are the registration and
|
|
2705
|
+
// the template never carries them, so they come through byte-identical.
|
|
2706
|
+
const fs = require('fs');
|
|
2707
|
+
const os = require('os');
|
|
2708
|
+
const jetpack = require('fs-jetpack');
|
|
2709
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
2710
|
+
|
|
2711
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
2712
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
2713
|
+
const origExit = process.exitCode;
|
|
2714
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
2715
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
2716
|
+
const shortcut = path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}acme.cmd`);
|
|
2717
|
+
const logged = [];
|
|
2718
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
2719
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2720
|
+
const templateDir = path.join(home, '_template');
|
|
2721
|
+
const orgDir = path.join(home, 'actions-runner-acme');
|
|
2722
|
+
const downloads = [];
|
|
2723
|
+
const spawned = [];
|
|
2724
|
+
// The registration files, exactly as the preflight leaves `.env`, so a
|
|
2725
|
+
// byte change can only have come from the copy.
|
|
2726
|
+
const kept = {
|
|
2727
|
+
'.runner': '{"agentName":"omega-runner-box-acme"}',
|
|
2728
|
+
'.credentials': '{"scheme":"OAuth"}',
|
|
2729
|
+
'.env': `https_proxy=http://proxy\nHOME=${path.join(home, 'home')}\nACTIONS_RUNNER_HOOK_JOB_STARTED=${path.join(home, 'job-started.js')}\n`,
|
|
2730
|
+
};
|
|
2731
|
+
try {
|
|
2732
|
+
jetpack.write(path.join(templateDir, 'config.cmd'), 'old config');
|
|
2733
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: '2.300.0', registeredOrgs: ['acme'] });
|
|
2734
|
+
jetpack.write(path.join(orgDir, 'config.cmd'), 'old config');
|
|
2735
|
+
jetpack.write(path.join(orgDir, 'bin', 'Runner.Listener.exe'), 'old listener');
|
|
2736
|
+
for (const [name, content] of Object.entries(kept)) jetpack.write(path.join(orgDir, name), content);
|
|
2737
|
+
jetpack.write(shortcut, '@echo off\r\n');
|
|
2738
|
+
|
|
2739
|
+
await runner({
|
|
2740
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
2741
|
+
_listeners: () => [],
|
|
2742
|
+
_spawn: (dir) => { spawned.push(dir); return { ok: true, pid: 5150 }; },
|
|
2743
|
+
_download: async (dir, h) => {
|
|
2744
|
+
downloads.push([dir, h]);
|
|
2745
|
+
jetpack.write(path.join(dir, 'config.cmd'), 'new config');
|
|
2746
|
+
jetpack.write(path.join(dir, 'bin', 'Runner.Listener.exe'), 'new listener');
|
|
2747
|
+
},
|
|
2748
|
+
_discoverOrgs: async () => ['acme'],
|
|
2749
|
+
_registerOrg: async () => { throw new Error('nothing to register'); },
|
|
2750
|
+
});
|
|
2751
|
+
|
|
2752
|
+
ctx.expect(downloads).toEqual([[templateDir, home]]);
|
|
2753
|
+
ctx.expect(fs.readFileSync(path.join(orgDir, 'config.cmd'), 'utf8')).toBe('new config');
|
|
2754
|
+
ctx.expect(fs.readFileSync(path.join(orgDir, 'bin', 'Runner.Listener.exe'), 'utf8')).toBe('new listener');
|
|
2755
|
+
for (const [name, content] of Object.entries(kept)) {
|
|
2756
|
+
ctx.expect(fs.readFileSync(path.join(orgDir, name), 'utf8')).toBe(content);
|
|
2757
|
+
}
|
|
2758
|
+
ctx.expect(jetpack.read(path.join(home, 'config.json'), 'json').actionsRunnerVersion).toBe(runner.ACTIONS_RUNNER_VERSION);
|
|
2759
|
+
ctx.expect(spawned).toEqual([orgDir]); // and the org still comes online
|
|
2760
|
+
ctx.expect(process.exitCode).toBe(origExit);
|
|
2761
|
+
} finally {
|
|
2762
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
2763
|
+
process.exitCode = origExit;
|
|
2764
|
+
jetpack.remove(shortcut);
|
|
2765
|
+
jetpack.remove(home);
|
|
2766
|
+
}
|
|
2767
|
+
},
|
|
2768
|
+
},
|
|
2769
|
+
{
|
|
2770
|
+
name: '`start` never refreshes an org whose listener is alive: its binaries are locked, so it names `restart` and the version stays unrecorded',
|
|
2771
|
+
run: async (ctx) => {
|
|
2772
|
+
// A live listener holds its dir's binaries open. Copying over them is a
|
|
2773
|
+
// half-updated runner, so that org is skipped with the command that
|
|
2774
|
+
// stops it first, and the box is not called refreshed until every org
|
|
2775
|
+
// dir took the new version.
|
|
2776
|
+
const fs = require('fs');
|
|
2777
|
+
const os = require('os');
|
|
2778
|
+
const jetpack = require('fs-jetpack');
|
|
2779
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
2780
|
+
|
|
2781
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
2782
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
2783
|
+
const origExit = process.exitCode;
|
|
2784
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
2785
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
2786
|
+
const orgs = ['acme', 'zeta'];
|
|
2787
|
+
const shortcuts = orgs.map((org) => path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}${org}.cmd`));
|
|
2788
|
+
const logged = [];
|
|
2789
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
2790
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2791
|
+
const templateDir = path.join(home, '_template');
|
|
2792
|
+
const aliveDir = path.join(home, 'actions-runner-acme');
|
|
2793
|
+
const stoppedDir = path.join(home, 'actions-runner-zeta');
|
|
2794
|
+
try {
|
|
2795
|
+
jetpack.write(path.join(templateDir, 'config.cmd'), 'old config');
|
|
2796
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: '2.300.0', registeredOrgs: orgs });
|
|
2797
|
+
for (const dir of [aliveDir, stoppedDir]) jetpack.write(path.join(dir, 'config.cmd'), 'old config');
|
|
2798
|
+
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
2799
|
+
|
|
2800
|
+
await runner({
|
|
2801
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
2802
|
+
_listeners: (dir) => (dir === aliveDir ? [{ pid: 4242, sessionId: 1, execPath: path.join(aliveDir, 'bin', 'Runner.Listener.exe') }] : []),
|
|
2803
|
+
_spawn: () => ({ ok: true, pid: 6000 }),
|
|
2804
|
+
_download: async (dir) => { jetpack.write(path.join(dir, 'config.cmd'), 'new config'); },
|
|
2805
|
+
_discoverOrgs: async () => orgs,
|
|
2806
|
+
_registerOrg: async () => { throw new Error('nothing to register'); },
|
|
2807
|
+
});
|
|
2808
|
+
|
|
2809
|
+
ctx.expect(fs.readFileSync(path.join(aliveDir, 'config.cmd'), 'utf8')).toBe('old config'); // untouched
|
|
2810
|
+
ctx.expect(fs.readFileSync(path.join(stoppedDir, 'config.cmd'), 'utf8')).toBe('new config'); // the stopped one took it
|
|
2811
|
+
const skip = logged.map((l) => l[1]).filter((l) => l.includes('npx omega runner restart'));
|
|
2812
|
+
ctx.expect(skip.length).toBe(1);
|
|
2813
|
+
ctx.expect(skip[0]).toContain('acme');
|
|
2814
|
+
ctx.expect(jetpack.read(path.join(home, 'config.json'), 'json').actionsRunnerVersion).toBe('2.300.0');
|
|
2815
|
+
} finally {
|
|
2816
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
2817
|
+
process.exitCode = origExit;
|
|
2818
|
+
for (const file of shortcuts) jetpack.remove(file);
|
|
2819
|
+
jetpack.remove(home);
|
|
2820
|
+
}
|
|
2821
|
+
},
|
|
2822
|
+
},
|
|
2823
|
+
{
|
|
2824
|
+
name: '`start` downloads nothing when the recorded actions/runner version is the pinned one',
|
|
2825
|
+
run: async (ctx) => {
|
|
2826
|
+
// The refresh is for a stale box only: a current one never pays for a
|
|
2827
|
+
// 150 MB download on every start.
|
|
2828
|
+
const fs = require('fs');
|
|
2829
|
+
const os = require('os');
|
|
2830
|
+
const jetpack = require('fs-jetpack');
|
|
2831
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
2832
|
+
|
|
2833
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
2834
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
2835
|
+
const origExit = process.exitCode;
|
|
2836
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
2837
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
2838
|
+
const shortcut = path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}acme.cmd`);
|
|
2839
|
+
const logged = [];
|
|
2840
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
2841
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2842
|
+
const orgDir = path.join(home, 'actions-runner-acme');
|
|
2843
|
+
const spawned = [];
|
|
2844
|
+
let downloads = 0;
|
|
2845
|
+
try {
|
|
2846
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), 'config');
|
|
2847
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION, registeredOrgs: ['acme'] });
|
|
2848
|
+
jetpack.write(path.join(orgDir, 'config.cmd'), 'config');
|
|
2849
|
+
jetpack.write(shortcut, '@echo off\r\n');
|
|
2850
|
+
|
|
2851
|
+
await runner({
|
|
2852
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
2853
|
+
_listeners: () => [],
|
|
2854
|
+
_spawn: (dir) => { spawned.push(dir); return { ok: true, pid: 7 }; },
|
|
2855
|
+
_download: async () => { downloads++; },
|
|
2856
|
+
_discoverOrgs: async () => ['acme'],
|
|
2857
|
+
_registerOrg: async () => { throw new Error('nothing to register'); },
|
|
2858
|
+
});
|
|
2859
|
+
|
|
2860
|
+
ctx.expect(downloads).toBe(0);
|
|
2861
|
+
ctx.expect(spawned).toEqual([orgDir]);
|
|
2862
|
+
} finally {
|
|
2863
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
2864
|
+
process.exitCode = origExit;
|
|
2865
|
+
jetpack.remove(shortcut);
|
|
2866
|
+
jetpack.remove(home);
|
|
2867
|
+
}
|
|
2868
|
+
},
|
|
2869
|
+
},
|
|
2870
|
+
{
|
|
2871
|
+
name: '`start` registers an admin org the box does not serve yet, honouring OMEGA_RUNNER_ORGS, and nothing already registered',
|
|
2872
|
+
run: async (ctx) => {
|
|
2873
|
+
// A new admin org used to need `install` again. `start` registers the
|
|
2874
|
+
// missing one itself: named by the filter, not yet in registeredOrgs.
|
|
2875
|
+
const fs = require('fs');
|
|
2876
|
+
const os = require('os');
|
|
2877
|
+
const jetpack = require('fs-jetpack');
|
|
2878
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
2879
|
+
|
|
2880
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
2881
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
2882
|
+
const origExit = process.exitCode;
|
|
2883
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
2884
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
2885
|
+
const shortcut = path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}acme.cmd`);
|
|
2886
|
+
const logged = [];
|
|
2887
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
2888
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2889
|
+
const registered = [];
|
|
2890
|
+
try {
|
|
2891
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), 'config');
|
|
2892
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION, registeredOrgs: ['acme'] });
|
|
2893
|
+
jetpack.write(path.join(home, 'actions-runner-acme', 'config.cmd'), 'config');
|
|
2894
|
+
jetpack.write(shortcut, '@echo off\r\n');
|
|
2895
|
+
|
|
2896
|
+
await runner({
|
|
2897
|
+
_: ['runner', 'start'], _home: home, _env: { ...filled, OMEGA_RUNNER_ORGS: 'acme, Beta' }, _logger: logger, _interactive: false, _prompt: {},
|
|
2898
|
+
_listeners: () => [],
|
|
2899
|
+
_spawn: () => ({ ok: true, pid: 8 }),
|
|
2900
|
+
_download: async () => { throw new Error('the version matches: no download'); },
|
|
2901
|
+
_discoverOrgs: async () => ['acme', 'beta', 'gamma'],
|
|
2902
|
+
_registerOrg: async (o) => { registered.push({ org: o._[2], home: o._home }); },
|
|
2903
|
+
});
|
|
2904
|
+
|
|
2905
|
+
// beta is named and new; acme is already served; gamma is not named.
|
|
2906
|
+
ctx.expect(registered).toEqual([{ org: 'beta', home }]);
|
|
2907
|
+
ctx.expect(process.exitCode).toBe(origExit);
|
|
2908
|
+
} finally {
|
|
2909
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
2910
|
+
process.exitCode = origExit;
|
|
2911
|
+
jetpack.remove(shortcut);
|
|
2912
|
+
jetpack.remove(home);
|
|
2913
|
+
}
|
|
2914
|
+
},
|
|
2915
|
+
},
|
|
2916
|
+
{
|
|
2917
|
+
name: '`start` works offline: an org discovery that throws is ONE skip line, and every registered org still comes up',
|
|
2918
|
+
run: async (ctx) => {
|
|
2919
|
+
// The org check is the only part of `start` that needs GitHub. A box
|
|
2920
|
+
// with no network still gets its listeners.
|
|
2921
|
+
const fs = require('fs');
|
|
2922
|
+
const os = require('os');
|
|
2923
|
+
const jetpack = require('fs-jetpack');
|
|
2924
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
2925
|
+
|
|
2926
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
2927
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
2928
|
+
const origExit = process.exitCode;
|
|
2929
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
2930
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
2931
|
+
const orgs = ['acme', 'zeta'];
|
|
2932
|
+
const shortcuts = orgs.map((org) => path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}${org}.cmd`));
|
|
2933
|
+
const logged = [];
|
|
2934
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
2935
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2936
|
+
const spawned = [];
|
|
2937
|
+
let registers = 0;
|
|
2938
|
+
try {
|
|
2939
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), 'config');
|
|
2940
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION, registeredOrgs: orgs });
|
|
2941
|
+
for (const org of orgs) jetpack.write(path.join(home, `actions-runner-${org}`, 'config.cmd'), 'config');
|
|
2942
|
+
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
2943
|
+
|
|
2944
|
+
await runner({
|
|
2945
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
2946
|
+
_listeners: () => [],
|
|
2947
|
+
_spawn: (dir) => { spawned.push(dir); return { ok: true, pid: 9 }; },
|
|
2948
|
+
_download: async () => { throw new Error('the version matches: no download'); },
|
|
2949
|
+
_discoverOrgs: async () => { throw new Error('getaddrinfo ENOTFOUND api.github.com'); },
|
|
2950
|
+
_registerOrg: async () => { registers++; },
|
|
2951
|
+
});
|
|
2952
|
+
|
|
2953
|
+
const skips = logged.map((l) => l[1]).filter((l) => /org check skipped/i.test(l));
|
|
2954
|
+
ctx.expect(skips.length).toBe(1);
|
|
2955
|
+
ctx.expect(skips[0]).toContain('ENOTFOUND');
|
|
2956
|
+
ctx.expect(registers).toBe(0);
|
|
2957
|
+
ctx.expect(spawned).toEqual(orgs.map((org) => path.join(home, `actions-runner-${org}`)));
|
|
2958
|
+
ctx.expect(process.exitCode).toBe(origExit);
|
|
2959
|
+
} finally {
|
|
2960
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
2961
|
+
process.exitCode = origExit;
|
|
2962
|
+
for (const file of shortcuts) jetpack.remove(file);
|
|
2963
|
+
jetpack.remove(home);
|
|
2964
|
+
}
|
|
2965
|
+
},
|
|
2966
|
+
},
|
|
2967
|
+
{
|
|
2968
|
+
name: '`start` in a test run never asks GitHub unless both GitHub seams are injected',
|
|
2969
|
+
run: async (ctx) => {
|
|
2970
|
+
// Registration is not home-scoped: a real `registerOrg` with a real
|
|
2971
|
+
// token registers the org on GitHub whatever scratch home the case
|
|
2972
|
+
// made. A test run without `_discoverOrgs` AND `_registerOrg` skips
|
|
2973
|
+
// the org check on one line, the way `uninstall` skips the surfaces no
|
|
2974
|
+
// path redirects.
|
|
2975
|
+
const fs = require('fs');
|
|
2976
|
+
const os = require('os');
|
|
2977
|
+
const jetpack = require('fs-jetpack');
|
|
2978
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
2979
|
+
|
|
2980
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
2981
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
2982
|
+
const origExit = process.exitCode;
|
|
2983
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
2984
|
+
const logged = [];
|
|
2985
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
2986
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
2987
|
+
let discovers = 0;
|
|
2988
|
+
try {
|
|
2989
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), 'config');
|
|
2990
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: runner.ACTIONS_RUNNER_VERSION, registeredOrgs: [] });
|
|
2991
|
+
|
|
2992
|
+
await runner({
|
|
2993
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
2994
|
+
_listeners: () => [],
|
|
2995
|
+
_spawn: () => ({ ok: true, pid: 10 }),
|
|
2996
|
+
_discoverOrgs: async () => { discovers++; return ['acme']; }, // no _registerOrg
|
|
2997
|
+
});
|
|
2998
|
+
|
|
2999
|
+
ctx.expect(discovers).toBe(0);
|
|
3000
|
+
const skips = logged.map((l) => l[1]).filter((l) => /org check skipped/i.test(l));
|
|
3001
|
+
ctx.expect(skips.length).toBe(1);
|
|
3002
|
+
ctx.expect(skips[0]).toContain('_registerOrg');
|
|
3003
|
+
} finally {
|
|
3004
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
3005
|
+
process.exitCode = origExit;
|
|
3006
|
+
jetpack.remove(home);
|
|
3007
|
+
}
|
|
3008
|
+
},
|
|
3009
|
+
},
|
|
3010
|
+
{
|
|
3011
|
+
name: '`self-update` is gone: the dispatcher calls it an unknown subcommand',
|
|
3012
|
+
run: async (ctx) => {
|
|
3013
|
+
// Every runner verb runs as `npx omega runner <verb>` from the box's
|
|
3014
|
+
// clone, so there is no global package for it to update (#937). The
|
|
3015
|
+
// home is one the test guard refuses, so no build of this command,
|
|
3016
|
+
// however old, can run a global npm install from this case.
|
|
3017
|
+
const os = require('os');
|
|
3018
|
+
const jetpack = require('fs-jetpack');
|
|
3019
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
3020
|
+
|
|
3021
|
+
const realish = path.join(os.homedir(), 'omega-runner-NOT-A-SCRATCH');
|
|
3022
|
+
let threw;
|
|
3023
|
+
try {
|
|
3024
|
+
await runner({ _: ['runner', 'self-update'], _home: realish });
|
|
3025
|
+
} catch (e) { threw = e; }
|
|
3026
|
+
ctx.expect(threw).toBeDefined();
|
|
3027
|
+
ctx.expect(threw.message).toBe('Unknown runner subcommand: self-update');
|
|
3028
|
+
ctx.expect(jetpack.exists(realish)).toBe(false);
|
|
3029
|
+
},
|
|
3030
|
+
},
|
|
3031
|
+
{
|
|
3032
|
+
name: '`start` called from install (`_reconcileDone`) skips the reconcile: no download and no org check, even on a stale version with a missing org',
|
|
3033
|
+
run: async (ctx) => {
|
|
3034
|
+
// install has just downloaded the template and registered every org, so
|
|
3035
|
+
// its closing start has nothing to reconcile, and a retry of an org that
|
|
3036
|
+
// failed there would print its error a second time.
|
|
3037
|
+
const fs = require('fs');
|
|
3038
|
+
const os = require('os');
|
|
3039
|
+
const jetpack = require('fs-jetpack');
|
|
3040
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
3041
|
+
|
|
3042
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
3043
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
3044
|
+
const origExit = process.exitCode;
|
|
3045
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
3046
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
3047
|
+
const shortcut = path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}acme.cmd`);
|
|
3048
|
+
const logged = [];
|
|
3049
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
3050
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
3051
|
+
const orgDir = path.join(home, 'actions-runner-acme');
|
|
3052
|
+
const spawned = [];
|
|
3053
|
+
let downloads = 0;
|
|
3054
|
+
let discovers = 0;
|
|
3055
|
+
let registers = 0;
|
|
3056
|
+
try {
|
|
3057
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), 'config');
|
|
3058
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: '2.300.0', registeredOrgs: ['acme'] });
|
|
3059
|
+
jetpack.write(path.join(orgDir, 'config.cmd'), 'config');
|
|
3060
|
+
jetpack.write(shortcut, '@echo off\r\n');
|
|
3061
|
+
|
|
3062
|
+
await runner({
|
|
3063
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
3064
|
+
_reconcileDone: true,
|
|
3065
|
+
_listeners: () => [],
|
|
3066
|
+
_spawn: (dir) => { spawned.push(dir); return { ok: true, pid: 11 }; },
|
|
3067
|
+
_download: async () => { downloads++; },
|
|
3068
|
+
_discoverOrgs: async () => { discovers++; return ['acme', 'beta']; },
|
|
3069
|
+
_registerOrg: async () => { registers++; },
|
|
3070
|
+
});
|
|
3071
|
+
|
|
3072
|
+
ctx.expect(downloads).toBe(0);
|
|
3073
|
+
ctx.expect(discovers).toBe(0);
|
|
3074
|
+
ctx.expect(registers).toBe(0);
|
|
3075
|
+
ctx.expect(jetpack.read(path.join(home, 'config.json'), 'json').actionsRunnerVersion).toBe('2.300.0');
|
|
3076
|
+
ctx.expect(spawned).toEqual([orgDir]); // the spawns still run
|
|
3077
|
+
} finally {
|
|
3078
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
3079
|
+
process.exitCode = origExit;
|
|
3080
|
+
jetpack.remove(shortcut);
|
|
3081
|
+
jetpack.remove(home);
|
|
3082
|
+
}
|
|
3083
|
+
},
|
|
3084
|
+
},
|
|
3085
|
+
{
|
|
3086
|
+
name: '`start` survives a refresh download that fails: one warn, no version recorded, every org still comes up',
|
|
3087
|
+
run: async (ctx) => {
|
|
3088
|
+
// A stale box with no network must still come online: the refresh is
|
|
3089
|
+
// skipped until the next start, never the whole run.
|
|
3090
|
+
const fs = require('fs');
|
|
3091
|
+
const os = require('os');
|
|
3092
|
+
const jetpack = require('fs-jetpack');
|
|
3093
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
3094
|
+
|
|
3095
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
3096
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
3097
|
+
const origExit = process.exitCode;
|
|
3098
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
3099
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
3100
|
+
const orgs = ['acme', 'zeta'];
|
|
3101
|
+
const shortcuts = orgs.map((org) => path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}${org}.cmd`));
|
|
3102
|
+
const logged = [];
|
|
3103
|
+
const logger = { log: (m) => logged.push(['log', String(m)]), warn: (m) => logged.push(['warn', String(m)]), error: (m) => logged.push(['error', String(m)]) };
|
|
3104
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
3105
|
+
const spawned = [];
|
|
3106
|
+
try {
|
|
3107
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), 'old config');
|
|
3108
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: '2.300.0', registeredOrgs: orgs });
|
|
3109
|
+
for (const org of orgs) jetpack.write(path.join(home, `actions-runner-${org}`, 'config.cmd'), 'old config');
|
|
3110
|
+
for (const file of shortcuts) jetpack.write(file, '@echo off\r\n');
|
|
3111
|
+
|
|
3112
|
+
await runner({
|
|
3113
|
+
_: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
3114
|
+
_listeners: () => [],
|
|
3115
|
+
_spawn: (dir) => { spawned.push(dir); return { ok: true, pid: 12 }; },
|
|
3116
|
+
_download: async () => { throw new Error('curl exit 6'); },
|
|
3117
|
+
_discoverOrgs: async () => orgs,
|
|
3118
|
+
_registerOrg: async () => { throw new Error('nothing to register'); },
|
|
3119
|
+
});
|
|
3120
|
+
|
|
3121
|
+
const warns = logged.filter((l) => l[0] === 'warn' && l[1].includes('curl exit 6'));
|
|
3122
|
+
ctx.expect(warns.length).toBe(1);
|
|
3123
|
+
ctx.expect(jetpack.read(path.join(home, 'config.json'), 'json').actionsRunnerVersion).toBe('2.300.0');
|
|
3124
|
+
for (const org of orgs) ctx.expect(fs.readFileSync(path.join(home, `actions-runner-${org}`, 'config.cmd'), 'utf8')).toBe('old config');
|
|
3125
|
+
ctx.expect(spawned).toEqual(orgs.map((org) => path.join(home, `actions-runner-${org}`)));
|
|
3126
|
+
ctx.expect(process.exitCode).toBe(origExit);
|
|
3127
|
+
} finally {
|
|
3128
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
3129
|
+
process.exitCode = origExit;
|
|
3130
|
+
for (const file of shortcuts) jetpack.remove(file);
|
|
3131
|
+
jetpack.remove(home);
|
|
3132
|
+
}
|
|
3133
|
+
},
|
|
3134
|
+
},
|
|
3135
|
+
{
|
|
3136
|
+
name: '`start` on a bare box in a test run refuses without an injected `_install`, and installs nothing',
|
|
3137
|
+
run: async (ctx) => {
|
|
3138
|
+
// The real install downloads, discovers and registers against GitHub.
|
|
3139
|
+
// A test run reaches it only through the seam, the way deregistration
|
|
3140
|
+
// refuses without its own.
|
|
3141
|
+
const fs = require('fs');
|
|
3142
|
+
const os = require('os');
|
|
3143
|
+
const jetpack = require('fs-jetpack');
|
|
3144
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
3145
|
+
|
|
3146
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
3147
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
3148
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
3149
|
+
const logger = { log: () => {}, warn: () => {}, error: () => {} };
|
|
3150
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
3151
|
+
try {
|
|
3152
|
+
let threw;
|
|
3153
|
+
try {
|
|
3154
|
+
await runner({ _: ['runner', 'start'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {}, _listeners: () => [], _spawn: () => ({ ok: true, pid: 13 }) });
|
|
3155
|
+
} catch (e) { threw = e; }
|
|
3156
|
+
ctx.expect(threw).toBeDefined();
|
|
3157
|
+
ctx.expect(threw.message).toContain('_install');
|
|
3158
|
+
ctx.expect(jetpack.exists(path.join(home, '_template'))).toBe(false);
|
|
3159
|
+
ctx.expect(jetpack.exists(path.join(home, '.env'))).toBe(false);
|
|
3160
|
+
} finally {
|
|
3161
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
3162
|
+
jetpack.remove(home);
|
|
3163
|
+
}
|
|
3164
|
+
},
|
|
3165
|
+
},
|
|
3166
|
+
{
|
|
3167
|
+
name: '`restart` refreshes a stale actions/runner AFTER its stop, once the listener is gone, and records the version',
|
|
3168
|
+
run: async (ctx) => {
|
|
3169
|
+
// The reconcile is not gated on restart's preflight: after the stop is
|
|
3170
|
+
// exactly when an org's binaries are free to be replaced.
|
|
3171
|
+
const fs = require('fs');
|
|
3172
|
+
const os = require('os');
|
|
3173
|
+
const jetpack = require('fs-jetpack');
|
|
3174
|
+
const runner = require(path.join(__dirname, '..', '..', '..', 'commands', 'runner.js'));
|
|
3175
|
+
|
|
3176
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'omega-runner-home-'));
|
|
3177
|
+
const origForce = process.env.OMEGA_RUNNER_FORCE;
|
|
3178
|
+
const origExit = process.exitCode;
|
|
3179
|
+
process.env.OMEGA_RUNNER_FORCE = '1';
|
|
3180
|
+
const hostPrefix = `omega-runner-${os.hostname().toLowerCase()}-`;
|
|
3181
|
+
const shortcut = path.join(SCRATCH_STARTUP_DIR, `${hostPrefix}acme.cmd`);
|
|
3182
|
+
const order = [];
|
|
3183
|
+
const logger = {
|
|
3184
|
+
log: (m) => { if (String(m).includes('already stopped')) order.push('stop'); },
|
|
3185
|
+
warn: () => {},
|
|
3186
|
+
error: () => {},
|
|
3187
|
+
};
|
|
3188
|
+
const filled = { GH_TOKEN: 'ghp_from_the_box', WIN_EV_TOKEN_PATH: 'a'.repeat(40), WIN_CSC_KEY_PASSWORD: '1234', SIGNTOOL_PATH: 'C:/sdk/signtool.exe' };
|
|
3189
|
+
const orgDir = path.join(home, 'actions-runner-acme');
|
|
3190
|
+
const spawned = [];
|
|
3191
|
+
try {
|
|
3192
|
+
jetpack.write(path.join(home, '_template', 'config.cmd'), 'old config');
|
|
3193
|
+
jetpack.write(path.join(home, 'config.json'), { actionsRunnerVersion: '2.300.0', registeredOrgs: ['acme'] });
|
|
3194
|
+
jetpack.write(path.join(orgDir, 'config.cmd'), 'old config');
|
|
3195
|
+
jetpack.write(shortcut, '@echo off\r\n');
|
|
3196
|
+
|
|
3197
|
+
// Alive for the first two polls, gone after.
|
|
3198
|
+
let looks = 0;
|
|
3199
|
+
await runner({
|
|
3200
|
+
_: ['runner', 'restart'], _home: home, _env: filled, _logger: logger, _interactive: false, _prompt: {},
|
|
3201
|
+
_delay: async () => {},
|
|
3202
|
+
_listeners: () => {
|
|
3203
|
+
const alive = ++looks <= 2;
|
|
3204
|
+
order.push(alive ? 'alive' : 'gone');
|
|
3205
|
+
return alive ? [{ pid: 909, sessionId: 1, execPath: path.join(orgDir, 'bin', 'Runner.Listener.exe') }] : [];
|
|
3206
|
+
},
|
|
3207
|
+
_spawn: (dir) => { spawned.push(dir); return { ok: true, pid: 14 }; },
|
|
3208
|
+
_download: async (dir) => { order.push('download'); jetpack.write(path.join(dir, 'config.cmd'), 'new config'); },
|
|
3209
|
+
_discoverOrgs: async () => ['acme'],
|
|
3210
|
+
_registerOrg: async () => { throw new Error('nothing to register'); },
|
|
3211
|
+
});
|
|
3212
|
+
|
|
3213
|
+
ctx.expect(order.indexOf('stop')).toBeGreaterThan(-1);
|
|
3214
|
+
ctx.expect(order.indexOf('download')).toBeGreaterThan(order.indexOf('stop'));
|
|
3215
|
+
ctx.expect(order.indexOf('download')).toBeGreaterThan(order.lastIndexOf('alive'));
|
|
3216
|
+
ctx.expect(fs.readFileSync(path.join(orgDir, 'config.cmd'), 'utf8')).toBe('new config');
|
|
3217
|
+
ctx.expect(jetpack.read(path.join(home, 'config.json'), 'json').actionsRunnerVersion).toBe(runner.ACTIONS_RUNNER_VERSION);
|
|
3218
|
+
ctx.expect(spawned).toEqual([orgDir]);
|
|
3219
|
+
ctx.expect(process.exitCode).toBe(origExit);
|
|
3220
|
+
} finally {
|
|
3221
|
+
if (origForce === undefined) delete process.env.OMEGA_RUNNER_FORCE; else process.env.OMEGA_RUNNER_FORCE = origForce;
|
|
3222
|
+
process.exitCode = origExit;
|
|
3223
|
+
jetpack.remove(shortcut);
|
|
3224
|
+
jetpack.remove(home);
|
|
3225
|
+
}
|
|
3226
|
+
},
|
|
3227
|
+
},
|
|
2621
3228
|
],
|
|
2622
3229
|
});
|