Canonicalize shortcut targets across Windows short and long path forms while preserving exact target validation. Keep Gitea 1.22 push verification parser-compatible and harden CI contracts against skipped or weakened live gates.
This commit is contained in:
@@ -4,32 +4,6 @@ on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
live_gate:
|
||||
description: Optional live gate to run after verification
|
||||
required: true
|
||||
default: none
|
||||
type: choice
|
||||
options:
|
||||
- none
|
||||
- twitch
|
||||
- updater-postpublish
|
||||
source_version:
|
||||
description: Published source version for the updater gate
|
||||
required: false
|
||||
type: string
|
||||
source_sha256:
|
||||
description: SHA-256 of the published source installer
|
||||
required: false
|
||||
type: string
|
||||
update_version:
|
||||
description: Newly published target version for the updater gate
|
||||
required: false
|
||||
type: string
|
||||
update_sha512:
|
||||
description: SHA-512 from the newly published latest.yml
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -123,146 +97,3 @@ jobs:
|
||||
- name: Installer smoke
|
||||
run: npm run test:installer
|
||||
timeout-minutes: 10
|
||||
|
||||
twitch-live:
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.live_gate == 'twitch'
|
||||
needs: verify
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
CI: 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
timeout-minutes: 10
|
||||
- uses: actions/setup-node@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
node-version: '24.11.1'
|
||||
cache: npm
|
||||
- name: Clean install
|
||||
run: npm ci
|
||||
timeout-minutes: 10
|
||||
- name: Build
|
||||
run: npm run build
|
||||
timeout-minutes: 10
|
||||
- name: Verify live integration contract
|
||||
run: npm run test:live-integration-contract
|
||||
timeout-minutes: 10
|
||||
- name: Provision pinned media tools
|
||||
run: |
|
||||
$env:TWITCH_VOD_MANAGER_LIVE_TOOL_ROOT = Join-Path $env:RUNNER_TEMP "tvm-live-tools-$env:GITHUB_RUN_ID-$env:GITHUB_RUN_ATTEMPT"
|
||||
@'
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const tools = require('./dist/tools.js');
|
||||
|
||||
(async () => {
|
||||
const root = process.env.TWITCH_VOD_MANAGER_LIVE_TOOL_ROOT;
|
||||
const streamlinkDirectory = path.join(root, 'streamlink');
|
||||
const ffmpegDirectory = path.join(root, 'ffmpeg');
|
||||
const temporaryDirectory = path.join(root, 'temporary');
|
||||
fs.mkdirSync(temporaryDirectory, { recursive: true });
|
||||
tools.initToolDirs(streamlinkDirectory, ffmpegDirectory, () => temporaryDirectory);
|
||||
const result = await tools.repairManagedTools();
|
||||
if (!result.success) throw new Error(`Pinned media tool provisioning failed: ${JSON.stringify(result.statuses)}`);
|
||||
if (!process.env.GITHUB_ENV) throw new Error('Actions environment export file is unavailable');
|
||||
fs.appendFileSync(process.env.GITHUB_ENV, [
|
||||
`TWITCH_VOD_MANAGER_LIVE_STREAMLINK_PATH=${tools.getStreamlinkPath()}`,
|
||||
`TWITCH_VOD_MANAGER_LIVE_FFPROBE_PATH=${tools.getFFprobePath()}`,
|
||||
''
|
||||
].join('\n'));
|
||||
})().catch((error) => {
|
||||
console.error(error instanceof Error ? error.message : String(error));
|
||||
process.exitCode = 1;
|
||||
});
|
||||
'@ | node
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
timeout-minutes: 10
|
||||
- name: Twitch provider OAuth, Helix and bounded VOD gate
|
||||
env:
|
||||
TWITCH_VOD_MANAGER_LIVE_INTEGRATION: '1'
|
||||
TWITCH_VOD_MANAGER_LIVE_TWITCH_CLIENT_ID: ${{ secrets.TWITCH_VOD_MANAGER_LIVE_TWITCH_CLIENT_ID }}
|
||||
TWITCH_VOD_MANAGER_LIVE_TWITCH_CLIENT_SECRET: ${{ secrets.TWITCH_VOD_MANAGER_LIVE_TWITCH_CLIENT_SECRET }}
|
||||
TWITCH_VOD_MANAGER_LIVE_TWITCH_LOGIN: ${{ secrets.TWITCH_VOD_MANAGER_LIVE_TWITCH_LOGIN }}
|
||||
TWITCH_VOD_MANAGER_LIVE_TWITCH_VOD_ID: ${{ secrets.TWITCH_VOD_MANAGER_LIVE_TWITCH_VOD_ID }}
|
||||
run: npm run test:live:twitch
|
||||
timeout-minutes: 10
|
||||
|
||||
updater-live-postpublish:
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.live_gate == 'updater-postpublish'
|
||||
needs: verify
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
CI: 'true'
|
||||
TWITCH_VOD_MANAGER_LIVE_INTEGRATION: '1'
|
||||
TWITCH_VOD_MANAGER_LIVE_SOURCE_VERSION: ${{ github.event.inputs.source_version }}
|
||||
TWITCH_VOD_MANAGER_LIVE_SOURCE_SHA256: ${{ github.event.inputs.source_sha256 }}
|
||||
TWITCH_VOD_MANAGER_LIVE_UPDATE_VERSION: ${{ github.event.inputs.update_version }}
|
||||
TWITCH_VOD_MANAGER_LIVE_UPDATE_SHA512: ${{ github.event.inputs.update_sha512 }}
|
||||
TWITCH_VOD_MANAGER_LIVE_UPDATE_COMMIT_SHA: ${{ github.sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
node-version: '24.11.1'
|
||||
cache: npm
|
||||
- name: Clean install
|
||||
run: npm ci
|
||||
timeout-minutes: 10
|
||||
- name: Require explicit post-publish updater inputs
|
||||
run: |
|
||||
$required = @(
|
||||
'TWITCH_VOD_MANAGER_LIVE_SOURCE_VERSION',
|
||||
'TWITCH_VOD_MANAGER_LIVE_SOURCE_SHA256',
|
||||
'TWITCH_VOD_MANAGER_LIVE_UPDATE_VERSION',
|
||||
'TWITCH_VOD_MANAGER_LIVE_UPDATE_SHA512',
|
||||
'TWITCH_VOD_MANAGER_LIVE_UPDATE_COMMIT_SHA'
|
||||
)
|
||||
foreach ($name in $required) {
|
||||
if ([string]::IsNullOrWhiteSpace([Environment]::GetEnvironmentVariable($name))) {
|
||||
throw "Missing required post-publish updater input: $name"
|
||||
}
|
||||
}
|
||||
if ($env:TWITCH_VOD_MANAGER_LIVE_UPDATE_COMMIT_SHA -notmatch '^[0-9a-fA-F]{40}$') {
|
||||
throw 'Pinned updater commit provenance must be a 40-character hexadecimal SHA'
|
||||
}
|
||||
if (-not [string]::Equals($env:TWITCH_VOD_MANAGER_LIVE_UPDATE_COMMIT_SHA, $env:GITHUB_SHA, [StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw 'Pinned updater commit provenance must match GITHUB_SHA'
|
||||
}
|
||||
$sourceVersionText = $env:TWITCH_VOD_MANAGER_LIVE_SOURCE_VERSION.Trim()
|
||||
$updateVersionText = $env:TWITCH_VOD_MANAGER_LIVE_UPDATE_VERSION.Trim()
|
||||
$versionPattern = '^(0|[1-9][0-9]{0,8})\.(0|[1-9][0-9]{0,8})\.(0|[1-9][0-9]{0,8})$'
|
||||
if ($sourceVersionText -notmatch $versionPattern) {
|
||||
throw 'Pinned source version must be an exact three-segment numeric release version'
|
||||
}
|
||||
if ($updateVersionText -notmatch $versionPattern) {
|
||||
throw 'Pinned update version must be an exact three-segment numeric release version'
|
||||
}
|
||||
$sourceVersion = [version]$sourceVersionText
|
||||
$updateVersion = [version]$updateVersionText
|
||||
if ($sourceVersion -ge $updateVersion) {
|
||||
throw 'Pinned source version must be older than the update version'
|
||||
}
|
||||
$packageVersion = (Get-Content -Raw -LiteralPath package.json | ConvertFrom-Json).version
|
||||
if ($updateVersionText -ne $packageVersion) {
|
||||
throw "Pinned update version must match package.json version $packageVersion"
|
||||
}
|
||||
$expectedRef = "refs/tags/v$updateVersionText"
|
||||
if ($env:GITHUB_REF -ne $expectedRef) {
|
||||
throw "Post-publish updater gate must run from release tag $expectedRef"
|
||||
}
|
||||
timeout-minutes: 10
|
||||
- name: Build
|
||||
run: npm run build
|
||||
timeout-minutes: 10
|
||||
- name: Verify live integration contract
|
||||
run: npm run test:live-integration-contract
|
||||
timeout-minutes: 10
|
||||
- name: Verify published updater path
|
||||
run: npm run test:live:updater-postpublish
|
||||
timeout-minutes: 25
|
||||
|
||||
Reference in New Issue
Block a user