mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-03 22:01:39 +00:00
Merge branch 'main' of https://github.com/GAM-team/GAM
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
This commit is contained in:
101
.github/workflows/build.yml
vendored
101
.github/workflows/build.yml
vendored
@@ -667,28 +667,67 @@ jobs:
|
||||
echo "GAM Version ${GAMVERSION}"
|
||||
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
||||
|
||||
- name: Install WinAppDriver
|
||||
# - name: Install WinAppDriver
|
||||
# if: runner.os == 'Windows'
|
||||
# run: |
|
||||
# choco install -y winappdriver
|
||||
|
||||
# - name: Enabled dev mode for WinAppDriver
|
||||
# if: runner.os == 'Windows'
|
||||
# shell: cmd
|
||||
# run : |
|
||||
# reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
||||
|
||||
- name: Nuke OneDrive (Prevent UI Interference)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host "Killing OneDrive process..."
|
||||
Stop-Process -Name "OneDrive" -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "Uninstalling OneDrive..."
|
||||
$setup64 = "$env:SystemRoot\SysWOW64\OneDriveSetup.exe"
|
||||
$setup32 = "$env:SystemRoot\System32\OneDriveSetup.exe"
|
||||
if (Test-Path $setup64) {
|
||||
Start-Process -FilePath $setup64 -ArgumentList "/uninstall" -Wait -NoNewWindow
|
||||
} elseif (Test-Path $setup32) {
|
||||
Start-Process -FilePath $setup32 -ArgumentList "/uninstall" -Wait -NoNewWindow
|
||||
}
|
||||
# Give the OS a moment to clean up the UI before moving on
|
||||
Start-Sleep -Seconds 5
|
||||
Write-Host "OneDrive eradicated."
|
||||
|
||||
- name: Initialize Windows Desktop Shell
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host "Checking for Windows Explorer shell..."
|
||||
if (-not (Get-Process -Name explorer -ErrorAction SilentlyContinue)) {
|
||||
Write-Host "Explorer not found. Booting the desktop shell..."
|
||||
Start-Process explorer.exe
|
||||
# Give the desktop a few seconds to fully render the taskbar
|
||||
Start-Sleep -Seconds 10
|
||||
} else {
|
||||
Write-Host "Explorer is already running."
|
||||
}
|
||||
Write-Host "Suppressing post-Explorer OneDrive popups..."
|
||||
# SAFE KILL: Only attempts to stop OneDrive if it is actually running
|
||||
Get-Process -Name "OneDrive" -ErrorAction SilentlyContinue | Stop-Process -Force
|
||||
# SAFE REGISTRY DELETE: Uses native PowerShell instead of reg.exe
|
||||
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "OneDrive" -ErrorAction SilentlyContinue
|
||||
Write-Host "Desktop initialized and OneDrive suppressed."
|
||||
exit 0
|
||||
|
||||
- name: Install NPM deps
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
choco install -y winappdriver
|
||||
|
||||
- name: Enabled dev mode for WinAppDriver
|
||||
if: runner.os == 'Windows'
|
||||
shell: cmd
|
||||
run : |
|
||||
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
||||
|
||||
- name: Install appium and totp tools
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
echo "Installing appium..."
|
||||
npm install -g appium
|
||||
echo "Installing totp-generator..."
|
||||
npm install "totp-generator"
|
||||
echo "Installing wdio..."
|
||||
npm install @wdio/cli
|
||||
echo "Installing appium win driver..."
|
||||
appium driver install windows
|
||||
#echo "Installing appium..."
|
||||
#npm install -g appium
|
||||
echo "Installing totp-generator and screenshot..."
|
||||
npm install totp-generator screenshot-desktop
|
||||
# echo "Installing wdio..."
|
||||
# npm install @wdio/cli
|
||||
# echo "Installing appium win driver..."
|
||||
# appium driver install windows
|
||||
|
||||
- name: Install Certum MSI
|
||||
if: runner.os == 'Windows'
|
||||
@@ -711,17 +750,27 @@ jobs:
|
||||
TOTP_SECRET: ${{ secrets.TOTP_SECRET }}
|
||||
run: |
|
||||
# disable win private firewall that interferes with appium server
|
||||
Set-NetFirewallProfile -Profile Private -Enabled False
|
||||
$appiumCmd = Get-Command appium
|
||||
$appiumPath = $appiumCmd.Path
|
||||
Start-Process -Filepath "powershell.exe" -ArgumentList "-File", $appiumPath, "--address", "127.0.0.1", "--log-level", "error"
|
||||
Start-Sleep -Seconds 10
|
||||
write-host "appium started"
|
||||
#Set-NetFirewallProfile -Profile Private -Enabled False
|
||||
#$appiumCmd = Get-Command appium
|
||||
#$appiumPath = $appiumCmd.Path
|
||||
#Start-Process -Filepath "powershell.exe" -ArgumentList "-File", $appiumPath, "--address", "127.0.0.1", "--log-level", "error"
|
||||
#Start-Sleep -Seconds 10
|
||||
#write-host "appium started"
|
||||
write-host "running SimplySignDesktop login..."
|
||||
node tools/ssd.mjs --log-level warn
|
||||
write-host "sleeping during login..."
|
||||
Start-Sleep 10
|
||||
|
||||
- name: Archive png artifacts
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0
|
||||
if: runner.os == 'Windows'
|
||||
with:
|
||||
archive: true
|
||||
name: images-${{ matrix.os }}
|
||||
if-no-files-found: ignore
|
||||
path: |
|
||||
*.png
|
||||
|
||||
- name: Sign gam.exe
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
|
||||
@@ -1,128 +1,133 @@
|
||||
// Node.js script that implements an Appium client which will launch
|
||||
// Simply Sign Desktop app and log a user in. Once logged in it should
|
||||
// be possible to use tools like signtool.exe to sign Windows EXE/MSI files
|
||||
// with the Certum certificate.
|
||||
// Node.js script to launch Simply Sign Desktop app and log a user in
|
||||
// using native Windows keystrokes and screenshot-desktop for reliable CI imaging.
|
||||
|
||||
import { Key, remote } from 'webdriverio';
|
||||
import { exec } from 'child_process';
|
||||
import { execSync, spawn } from 'child_process';
|
||||
import { TOTP } from 'totp-generator';
|
||||
|
||||
async function screenshot(driver, filename) {
|
||||
// uncomment to save .png screenshots
|
||||
await driver.saveScreenshot(filename);
|
||||
return
|
||||
}
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import screenshot from 'screenshot-desktop';
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function executeCommand(command) {
|
||||
// Native PowerShell Keystroke Sender
|
||||
function sendKeys(keys) {
|
||||
const script = `$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('${keys}')`;
|
||||
execSync(`powershell -Command "${script}"`);
|
||||
}
|
||||
|
||||
// Native PowerShell Desktop Clear
|
||||
function minimizeAllWindows() {
|
||||
console.log('Minimizing all rogue background windows...');
|
||||
const script = `$shell = New-Object -ComObject "Shell.Application"; $shell.MinimizeAll()`;
|
||||
try {
|
||||
let { stdout, stderr } = await exec(command);
|
||||
return stdout;
|
||||
} catch (error) {
|
||||
console.error(`Error executing command: ${command}`);
|
||||
console.error(`Error details: ${error}`);
|
||||
throw error;
|
||||
execSync(`powershell -Command "${script}"`);
|
||||
} catch (err) {
|
||||
console.log('Minimize command failed silently.');
|
||||
}
|
||||
}
|
||||
|
||||
// Reliable Screen Capture using screenshot-desktop
|
||||
async function takeScreenshot(filename) {
|
||||
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
|
||||
const fullPath = path.join(workspace, filename);
|
||||
|
||||
try {
|
||||
await screenshot({ filename: fullPath });
|
||||
console.log(`Saved screenshot: ${fullPath}`);
|
||||
} catch (err) {
|
||||
console.error(`Failed to save screenshot ${fullPath}:`, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Fire and forget application launcher
|
||||
function launchSSD() {
|
||||
const child = spawn('C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe', [], {
|
||||
detached: true,
|
||||
stdio: 'ignore'
|
||||
});
|
||||
child.unref();
|
||||
}
|
||||
|
||||
async function runSSD() {
|
||||
const opts = {
|
||||
port: 4723,
|
||||
logLevel: "silent",
|
||||
capabilities: {
|
||||
platformName: "Windows",
|
||||
"appium:app": "C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe",
|
||||
"appium:automationName": "Windows",
|
||||
},
|
||||
};
|
||||
await takeScreenshot('001.png');
|
||||
minimizeAllWindows();
|
||||
await sleep(2000);
|
||||
await takeScreenshot('002.png');
|
||||
sendKeys('{ESC}');
|
||||
await sleep(2000);
|
||||
await takeScreenshot('003.png');
|
||||
//sendKeys('{ESC}');
|
||||
//await sleep(2000);
|
||||
//await takeScreenshot('004.png');
|
||||
//sendKeys('{ESC}');
|
||||
//await sleep(2000);
|
||||
//await takeScreenshot('005.png');
|
||||
//sendKeys('%{F4}');
|
||||
//await sleep(2000);
|
||||
//await takeScreenshot('006.png');
|
||||
//sendKeys('%{F4}');
|
||||
//await sleep(2000);
|
||||
//await takeScreenshot('007.png');
|
||||
|
||||
let driver;
|
||||
// Re-execute SSD to open login dialog
|
||||
launchSSD();
|
||||
await sleep(3000);
|
||||
await takeScreenshot('008.png');
|
||||
launchSSD();
|
||||
await sleep(3000);
|
||||
await takeScreenshot('009.png');
|
||||
|
||||
// 2. Login Flow
|
||||
console.log('Typing credentials...');
|
||||
|
||||
// Type Email
|
||||
sendKeys('jay0lee@gmail.com');
|
||||
await sleep(500);
|
||||
await takeScreenshot('010.png');
|
||||
|
||||
// Tab to next field
|
||||
sendKeys('{TAB}');
|
||||
await sleep(500);
|
||||
|
||||
// Generate and type TOTP
|
||||
console.log(`Our secret is ${process.env.TOTP_SECRET.length} characters.`);
|
||||
const { otp } = await TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'});
|
||||
console.log(`Our token is ${otp.length} characters.`);
|
||||
|
||||
sendKeys(otp);
|
||||
await sleep(500);
|
||||
await takeScreenshot('011.png');
|
||||
|
||||
// Submit
|
||||
sendKeys('{ENTER}');
|
||||
console.log('Login sequence complete.');
|
||||
|
||||
// Screenshot cascade to monitor the window closing
|
||||
await takeScreenshot('012.png');
|
||||
await sleep(500);
|
||||
await takeScreenshot('013.png');
|
||||
await sleep(500);
|
||||
await takeScreenshot('014.png');
|
||||
await sleep(500);
|
||||
|
||||
|
||||
console.log('Exiting script, leaving SimplySign running in background.');
|
||||
|
||||
// Verification block to list all PNGs in the workspace
|
||||
console.log('\n--- Screenshot Verification ---');
|
||||
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
|
||||
try {
|
||||
driver = await remote(opts);
|
||||
|
||||
// Github Actions Win ARM64 is stuck on a OOB screen that steals focus
|
||||
// These enter / escapes should dismiss it.
|
||||
const runner_arch = process.env.RUNNER_ARCH;
|
||||
if ( runner_arch === "ARM64" ) {
|
||||
console.log('Running on ARM64...');
|
||||
await sleep(3000); // Pause execution for 3 seconds
|
||||
await screenshot(driver, 'oob1.png');
|
||||
await driver.sendKeys([Key.Enter]);
|
||||
await sleep(3000); // Pause execution for 3 seconds
|
||||
await screenshot(driver, 'oob2.png');
|
||||
await driver.sendKeys([Key.Enter]);
|
||||
await sleep(3000); // Pause execution for 3 seconds
|
||||
await screenshot(driver, 'oob3.png');
|
||||
await driver.sendKeys([Key.Escape]);
|
||||
await screenshot(driver, 'oob6.png');
|
||||
} else {
|
||||
console.log('NOT running on ARM64');
|
||||
}
|
||||
|
||||
// Execute SSD again to open login dialog
|
||||
exec('"C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe"', (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`exec error: ${error}`);
|
||||
return;
|
||||
}
|
||||
});
|
||||
await sleep(3000);
|
||||
|
||||
// Login
|
||||
const windows = await driver.getWindowHandles();
|
||||
const login_window = windows[0]
|
||||
await driver.switchWindow(login_window);
|
||||
await screenshot(driver, 'login01.png');
|
||||
const id_value = 'jay0lee@gmail.com';
|
||||
const id_arr = [...id_value];
|
||||
await driver.sendKeys(id_arr);
|
||||
await screenshot(driver, 'login02.png');
|
||||
await driver.sendKeys([Key.Tab]);
|
||||
console.log('Our secret is ' + process.env.TOTP_SECRET.length + ' characters.');
|
||||
// We wait until the last possible second to generate
|
||||
// our TOTP to ensure it's still valid.
|
||||
const { otp } = await TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'});
|
||||
console.log('Our token is ' + otp.length + ' characters.');
|
||||
const otp_arr = [...otp];
|
||||
await driver.sendKeys(otp_arr);
|
||||
await screenshot(driver, 'login03.png');
|
||||
await driver.sendKeys([Key.Enter]);
|
||||
|
||||
// TODO: it's expected that on successful login the window
|
||||
// will close and these screenshots will error out. Figure
|
||||
// out how to handle that gracefully.
|
||||
await screenshot(driver, 'login04.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login05.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login06.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login07.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login08.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login09.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login10.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login11.png');
|
||||
await sleep(500);
|
||||
await screenshot(driver, 'login12.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
//console.error("Error during Appium run:");
|
||||
const files = fs.readdirSync(workspace);
|
||||
const pngFiles = files.filter(f => f.endsWith('.png'));
|
||||
console.log(`Target Directory: ${workspace}`);
|
||||
console.log(`Found ${pngFiles.length} .png files:`);
|
||||
pngFiles.forEach(f => console.log(` - ${f}`));
|
||||
} catch (err) {
|
||||
console.error(`Error reading directory ${workspace}:`, err.message);
|
||||
}
|
||||
|
||||
// INTENTIONAL Keep driver open so tray icon for Certum doesn't close
|
||||
// finally {
|
||||
// if (driver) {
|
||||
// await driver.deleteSession(); // Close the Appium session
|
||||
// }
|
||||
//}
|
||||
console.log('-------------------------------\n');
|
||||
}
|
||||
|
||||
runSSD();
|
||||
|
||||
Reference in New Issue
Block a user