mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-04 04:41:35 +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:
97
.github/workflows/build.yml
vendored
97
.github/workflows/build.yml
vendored
@@ -667,28 +667,67 @@ jobs:
|
|||||||
echo "GAM Version ${GAMVERSION}"
|
echo "GAM Version ${GAMVERSION}"
|
||||||
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Install WinAppDriver
|
# - name: Install WinAppDriver
|
||||||
if: runner.os == 'Windows'
|
# if: runner.os == 'Windows'
|
||||||
run: |
|
# run: |
|
||||||
choco install -y winappdriver
|
# choco install -y winappdriver
|
||||||
|
|
||||||
- name: Enabled dev mode for WinAppDriver
|
# - name: Enabled dev mode for WinAppDriver
|
||||||
if: runner.os == 'Windows'
|
# if: runner.os == 'Windows'
|
||||||
shell: cmd
|
# shell: cmd
|
||||||
run : |
|
# run : |
|
||||||
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
# reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
||||||
|
|
||||||
- name: Install appium and totp tools
|
- 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'
|
if: runner.os == 'Windows'
|
||||||
run: |
|
run: |
|
||||||
echo "Installing appium..."
|
#echo "Installing appium..."
|
||||||
npm install -g appium
|
#npm install -g appium
|
||||||
echo "Installing totp-generator..."
|
echo "Installing totp-generator and screenshot..."
|
||||||
npm install "totp-generator"
|
npm install totp-generator screenshot-desktop
|
||||||
echo "Installing wdio..."
|
# echo "Installing wdio..."
|
||||||
npm install @wdio/cli
|
# npm install @wdio/cli
|
||||||
echo "Installing appium win driver..."
|
# echo "Installing appium win driver..."
|
||||||
appium driver install windows
|
# appium driver install windows
|
||||||
|
|
||||||
- name: Install Certum MSI
|
- name: Install Certum MSI
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
@@ -711,17 +750,27 @@ jobs:
|
|||||||
TOTP_SECRET: ${{ secrets.TOTP_SECRET }}
|
TOTP_SECRET: ${{ secrets.TOTP_SECRET }}
|
||||||
run: |
|
run: |
|
||||||
# disable win private firewall that interferes with appium server
|
# disable win private firewall that interferes with appium server
|
||||||
Set-NetFirewallProfile -Profile Private -Enabled False
|
#Set-NetFirewallProfile -Profile Private -Enabled False
|
||||||
$appiumCmd = Get-Command appium
|
#$appiumCmd = Get-Command appium
|
||||||
$appiumPath = $appiumCmd.Path
|
#$appiumPath = $appiumCmd.Path
|
||||||
Start-Process -Filepath "powershell.exe" -ArgumentList "-File", $appiumPath, "--address", "127.0.0.1", "--log-level", "error"
|
#Start-Process -Filepath "powershell.exe" -ArgumentList "-File", $appiumPath, "--address", "127.0.0.1", "--log-level", "error"
|
||||||
Start-Sleep -Seconds 10
|
#Start-Sleep -Seconds 10
|
||||||
write-host "appium started"
|
#write-host "appium started"
|
||||||
write-host "running SimplySignDesktop login..."
|
write-host "running SimplySignDesktop login..."
|
||||||
node tools/ssd.mjs --log-level warn
|
node tools/ssd.mjs --log-level warn
|
||||||
write-host "sleeping during login..."
|
write-host "sleeping during login..."
|
||||||
Start-Sleep 10
|
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
|
- name: Sign gam.exe
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|||||||
@@ -1,128 +1,133 @@
|
|||||||
// Node.js script that implements an Appium client which will launch
|
// Node.js script to launch Simply Sign Desktop app and log a user in
|
||||||
// Simply Sign Desktop app and log a user in. Once logged in it should
|
// using native Windows keystrokes and screenshot-desktop for reliable CI imaging.
|
||||||
// be possible to use tools like signtool.exe to sign Windows EXE/MSI files
|
|
||||||
// with the Certum certificate.
|
|
||||||
|
|
||||||
import { Key, remote } from 'webdriverio';
|
import { execSync, spawn } from 'child_process';
|
||||||
import { exec } from 'child_process';
|
|
||||||
import { TOTP } from 'totp-generator';
|
import { TOTP } from 'totp-generator';
|
||||||
|
import path from 'path';
|
||||||
async function screenshot(driver, filename) {
|
import fs from 'fs';
|
||||||
// uncomment to save .png screenshots
|
import screenshot from 'screenshot-desktop';
|
||||||
await driver.saveScreenshot(filename);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeCommand(command) {
|
// Native PowerShell Keystroke Sender
|
||||||
try {
|
function sendKeys(keys) {
|
||||||
let { stdout, stderr } = await exec(command);
|
const script = `$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('${keys}')`;
|
||||||
return stdout;
|
execSync(`powershell -Command "${script}"`);
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error executing command: ${command}`);
|
|
||||||
console.error(`Error details: ${error}`);
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Native PowerShell Desktop Clear
|
||||||
|
function minimizeAllWindows() {
|
||||||
|
console.log('Minimizing all rogue background windows...');
|
||||||
|
const script = `$shell = New-Object -ComObject "Shell.Application"; $shell.MinimizeAll()`;
|
||||||
|
try {
|
||||||
|
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() {
|
async function runSSD() {
|
||||||
const opts = {
|
await takeScreenshot('001.png');
|
||||||
port: 4723,
|
minimizeAllWindows();
|
||||||
logLevel: "silent",
|
await sleep(2000);
|
||||||
capabilities: {
|
await takeScreenshot('002.png');
|
||||||
platformName: "Windows",
|
sendKeys('{ESC}');
|
||||||
"appium:app": "C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe",
|
await sleep(2000);
|
||||||
"appium:automationName": "Windows",
|
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
|
||||||
try {
|
launchSSD();
|
||||||
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);
|
await sleep(3000);
|
||||||
|
await takeScreenshot('008.png');
|
||||||
|
launchSSD();
|
||||||
|
await sleep(3000);
|
||||||
|
await takeScreenshot('009.png');
|
||||||
|
|
||||||
// Login
|
// 2. Login Flow
|
||||||
const windows = await driver.getWindowHandles();
|
console.log('Typing credentials...');
|
||||||
const login_window = windows[0]
|
|
||||||
await driver.switchWindow(login_window);
|
// Type Email
|
||||||
await screenshot(driver, 'login01.png');
|
sendKeys('jay0lee@gmail.com');
|
||||||
const id_value = 'jay0lee@gmail.com';
|
await sleep(500);
|
||||||
const id_arr = [...id_value];
|
await takeScreenshot('010.png');
|
||||||
await driver.sendKeys(id_arr);
|
|
||||||
await screenshot(driver, 'login02.png');
|
// Tab to next field
|
||||||
await driver.sendKeys([Key.Tab]);
|
sendKeys('{TAB}');
|
||||||
console.log('Our secret is ' + process.env.TOTP_SECRET.length + ' characters.');
|
await sleep(500);
|
||||||
// We wait until the last possible second to generate
|
|
||||||
// our TOTP to ensure it's still valid.
|
// 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'});
|
const { otp } = await TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'});
|
||||||
console.log('Our token is ' + otp.length + ' characters.');
|
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
|
sendKeys(otp);
|
||||||
// will close and these screenshots will error out. Figure
|
|
||||||
// out how to handle that gracefully.
|
|
||||||
await screenshot(driver, 'login04.png');
|
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
await screenshot(driver, 'login05.png');
|
await takeScreenshot('011.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) {
|
// Submit
|
||||||
console.error(error);
|
sendKeys('{ENTER}');
|
||||||
//console.error("Error during Appium run:");
|
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 {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
console.log('-------------------------------\n');
|
||||||
// INTENTIONAL Keep driver open so tray icon for Certum doesn't close
|
|
||||||
// finally {
|
|
||||||
// if (driver) {
|
|
||||||
// await driver.deleteSession(); // Close the Appium session
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runSSD();
|
runSSD();
|
||||||
|
|||||||
Reference in New Issue
Block a user