Ecosystem smoke #436
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Ecosystem smoke | |
| on: | |
| schedule: | |
| - cron: "17 */4 * * *" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ecosystem-smoke | |
| cancel-in-progress: true | |
| env: | |
| VASTLINT_VERSION: "0.4.22" | |
| VALID_FIXTURE: crates/vastlint-core/tests/fixtures/valid_4.2.xml | |
| INVALID_FIXTURE: crates/vastlint-core/tests/fixtures/err_no_ad.xml | |
| jobs: | |
| smoke-cli: | |
| name: Smoke published CLI | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v (pinned SHA) | |
| with: | |
| toolchain: stable | |
| - name: Install published vastlint CLI | |
| run: | | |
| INSTALL_ROOT="$RUNNER_TEMP/vastlint-cli" | |
| cargo install --locked vastlint-cli --version "$VASTLINT_VERSION" --root "$INSTALL_ROOT" | |
| echo "$INSTALL_ROOT/bin" >> "$GITHUB_PATH" | |
| - name: Validate fixtures with published CLI | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| valid_json="$RUNNER_TEMP/valid-cli.json" | |
| invalid_json="$RUNNER_TEMP/invalid-cli.json" | |
| vastlint check "$VALID_FIXTURE" --format json > "$valid_json" | |
| set +e | |
| vastlint check "$INVALID_FIXTURE" --format json > "$invalid_json" | |
| exit_code=$? | |
| set -e | |
| if [ "$exit_code" -eq 0 ]; then | |
| echo "Expected invalid fixture to fail the CLI smoke test" | |
| exit 1 | |
| fi | |
| python3 -c 'import json, sys; valid = json.load(open(sys.argv[1], encoding="utf-8")); invalid = json.load(open(sys.argv[2], encoding="utf-8")); assert valid["summary"]["errors"] == 0, valid; assert invalid["summary"]["errors"] > 0, invalid; print("CLI smoke passed")' "$valid_json" "$invalid_json" | |
| smoke-rust-core: | |
| name: Smoke published Rust crate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v (pinned SHA) | |
| with: | |
| toolchain: stable | |
| - name: Build disposable Rust app with vastlint-core | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| APP_DIR="$RUNNER_TEMP/vastlint-core-smoke" | |
| mkdir -p "$APP_DIR/src" | |
| printf '%s\n' \ | |
| '[package]' \ | |
| 'name = "vastlint-core-smoke"' \ | |
| 'version = "0.1.0"' \ | |
| 'edition = "2021"' \ | |
| '' \ | |
| '[dependencies]' \ | |
| "vastlint-core = { version = \"=${VASTLINT_VERSION}\" }" \ | |
| > "$APP_DIR/Cargo.toml" | |
| printf '%s\n' \ | |
| 'use std::{env, fs};' \ | |
| 'use vastlint_core::validate;' \ | |
| '' \ | |
| 'fn main() {' \ | |
| ' let mut args = env::args().skip(1);' \ | |
| ' let valid_path = args.next().expect("valid fixture path");' \ | |
| ' let invalid_path = args.next().expect("invalid fixture path");' \ | |
| '' \ | |
| ' let valid = validate(&fs::read_to_string(valid_path).expect("read valid fixture"));' \ | |
| ' assert_eq!(valid.summary.errors, 0, "expected valid fixture to have zero errors");' \ | |
| '' \ | |
| ' let invalid = validate(&fs::read_to_string(invalid_path).expect("read invalid fixture"));' \ | |
| ' assert!(invalid.summary.errors > 0, "expected invalid fixture to have errors");' \ | |
| '' \ | |
| ' println!("Rust crate smoke passed ({} errors on invalid fixture)", invalid.summary.errors);' \ | |
| '}' \ | |
| > "$APP_DIR/src/main.rs" | |
| cargo run --quiet --manifest-path "$APP_DIR/Cargo.toml" -- \ | |
| "$GITHUB_WORKSPACE/$VALID_FIXTURE" \ | |
| "$GITHUB_WORKSPACE/$INVALID_FIXTURE" | |
| smoke-npm: | |
| name: Smoke published npm packages | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '24' | |
| package-manager-cache: false | |
| - name: Install published vastlint npm package in a clean app | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| APP_DIR="$RUNNER_TEMP/vastlint-npm-smoke" | |
| mkdir -p "$APP_DIR" | |
| printf '%s\n' \ | |
| '{' \ | |
| ' "name": "vastlint-npm-smoke",' \ | |
| ' "private": true,' \ | |
| ' "type": "module"' \ | |
| '}' \ | |
| > "$APP_DIR/package.json" | |
| pushd "$APP_DIR" >/dev/null | |
| PACKED_TARBALL="$(npm pack "vastlint@${VASTLINT_VERSION}" --silent)" | |
| mkdir -p node_modules | |
| tar -xzf "$PACKED_TARBALL" -C node_modules | |
| mv node_modules/package node_modules/vastlint | |
| rm "$PACKED_TARBALL" | |
| printf '%s\n' \ | |
| "import fs from 'node:fs';" \ | |
| "import { validate } from 'vastlint';" \ | |
| '' \ | |
| 'const [validPath, invalidPath] = process.argv.slice(2);' \ | |
| '' \ | |
| "const valid = validate(fs.readFileSync(validPath, 'utf8'));" \ | |
| 'if (!valid.summary.valid || valid.summary.errors !== 0) {' \ | |
| ' throw new Error("expected valid fixture to pass: " + JSON.stringify(valid.summary));' \ | |
| '}' \ | |
| '' \ | |
| "const invalid = validate(fs.readFileSync(invalidPath, 'utf8'));" \ | |
| 'if (invalid.summary.valid || invalid.summary.errors === 0) {' \ | |
| ' throw new Error("expected invalid fixture to fail: " + JSON.stringify(invalid.summary));' \ | |
| '}' \ | |
| '' \ | |
| 'console.log("npm smoke passed (" + invalid.summary.errors + " errors on invalid fixture)");' \ | |
| > smoke.mjs | |
| node smoke.mjs \ | |
| "$GITHUB_WORKSPACE/$VALID_FIXTURE" \ | |
| "$GITHUB_WORKSPACE/$INVALID_FIXTURE" | |
| popd >/dev/null | |
| - name: Install published vastlint-client npm package in a clean app | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| APP_DIR="$RUNNER_TEMP/vastlint-client-smoke" | |
| mkdir -p "$APP_DIR" | |
| printf '%s\n' \ | |
| '{' \ | |
| ' "name": "vastlint-client-smoke",' \ | |
| ' "private": true,' \ | |
| ' "type": "module"' \ | |
| '}' \ | |
| > "$APP_DIR/package.json" | |
| pushd "$APP_DIR" >/dev/null | |
| PACKED_TARBALL="$(npm pack "vastlint-client@${VASTLINT_VERSION}" --silent)" | |
| npm install --no-package-lock --ignore-scripts "./$PACKED_TARBALL" | |
| rm "$PACKED_TARBALL" | |
| cat > smoke.mjs <<'EOF' | |
| import fs from 'node:fs'; | |
| import { | |
| createVastPlaybackController, | |
| createVastSession, | |
| selectResolvedAdMediaFile, | |
| selectTrackingTargets, | |
| } from 'vastlint-client'; | |
| const [validPath, invalidPath] = process.argv.slice(2); | |
| const playbackFixture = `<?xml version="1.0" encoding="UTF-8"?> | |
| <VAST version="4.2"> | |
| <Ad id="playback-1"> | |
| <InLine> | |
| <AdSystem>Playback Demo</AdSystem> | |
| <AdTitle>Playback Fixture</AdTitle> | |
| <Error><![CDATA[https://track.example.com/error?code=%%ERRORCODE%%]]></Error> | |
| <Impression><![CDATA[https://track.example.com/impression]]></Impression> | |
| <Creatives> | |
| <Creative> | |
| <Linear> | |
| <Duration>00:00:20</Duration> | |
| <TrackingEvents> | |
| <Tracking event="creativeView"><![CDATA[https://track.example.com/creative-view]]></Tracking> | |
| <Tracking event="start"><![CDATA[https://track.example.com/start]]></Tracking> | |
| <Tracking event="firstQuartile"><![CDATA[https://track.example.com/first-quartile]]></Tracking> | |
| </TrackingEvents> | |
| <VideoClicks> | |
| <ClickThrough><![CDATA[https://click.example.com/landing]]></ClickThrough> | |
| <ClickTracking><![CDATA[https://track.example.com/click]]></ClickTracking> | |
| </VideoClicks> | |
| <MediaFiles> | |
| <MediaFile delivery="progressive" type="video/mp4" width="1280" height="720"><![CDATA[https://cdn.example.com/video.mp4]]></MediaFile> | |
| </MediaFiles> | |
| </Linear> | |
| </Creative> | |
| </Creatives> | |
| </InLine> | |
| </Ad> | |
| </VAST>`; | |
| function createPixelResponse() { | |
| return { | |
| ok: true, | |
| status: 204, | |
| statusText: 'No Content', | |
| async text() { | |
| return ''; | |
| }, | |
| }; | |
| } | |
| const validSession = createVastSession({ | |
| source: { kind: 'xml', xml: fs.readFileSync(validPath, 'utf8') }, | |
| }); | |
| const validResult = await validSession.validate(); | |
| if (!validResult.summary.valid || validResult.summary.errors !== 0) { | |
| throw new Error('expected valid fixture to pass: ' + JSON.stringify(validResult.summary)); | |
| } | |
| const invalidSession = createVastSession({ | |
| source: { kind: 'xml', xml: fs.readFileSync(invalidPath, 'utf8') }, | |
| }); | |
| const invalidResult = await invalidSession.validate(); | |
| if (invalidResult.summary.valid || invalidResult.summary.errors === 0) { | |
| throw new Error('expected invalid fixture to fail: ' + JSON.stringify(invalidResult.summary)); | |
| } | |
| const trackingCalls = []; | |
| const playbackSession = createVastSession({ | |
| source: { kind: 'xml', xml: playbackFixture }, | |
| fetch: async (url) => { | |
| trackingCalls.push(String(url)); | |
| return createPixelResponse(); | |
| }, | |
| }); | |
| await playbackSession.resolve(); | |
| const playbackSnapshot = playbackSession.getSnapshot(); | |
| if (!playbackSnapshot.resolvedAd?.resolved) { | |
| throw new Error('expected playback fixture to resolve to an inline ad'); | |
| } | |
| const mediaSelection = selectResolvedAdMediaFile(playbackSnapshot.resolvedAd, { | |
| supportedMimeTypes: ['video/mp4'], | |
| }); | |
| if (mediaSelection.selected?.url !== 'https://cdn.example.com/video.mp4') { | |
| throw new Error('expected playback fixture media to be selected'); | |
| } | |
| const startTargets = selectTrackingTargets(playbackSession.getSnapshot().tracking.plan, 'start'); | |
| if (startTargets.length !== 1) { | |
| throw new Error('expected one start tracking target, got ' + startTargets.length); | |
| } | |
| const playback = createVastPlaybackController({ | |
| session: playbackSession, | |
| autoResolve: false, | |
| mediaSelection: { | |
| supportedMimeTypes: ['video/mp4'], | |
| }, | |
| }); | |
| await playback.initialize(); | |
| await playback.start(); | |
| if (playback.getSnapshot().status !== 'playing') { | |
| throw new Error('expected playback controller to enter playing state'); | |
| } | |
| for (const url of [ | |
| 'https://track.example.com/impression', | |
| 'https://track.example.com/creative-view', | |
| 'https://track.example.com/start', | |
| ]) { | |
| if (!trackingCalls.includes(url)) { | |
| throw new Error('expected playback tracking call for ' + url); | |
| } | |
| } | |
| console.log('vastlint-client smoke passed'); | |
| EOF | |
| node smoke.mjs \ | |
| "$GITHUB_WORKSPACE/$VALID_FIXTURE" \ | |
| "$GITHUB_WORKSPACE/$INVALID_FIXTURE" | |
| popd >/dev/null | |
| - name: Install published vastlint-react npm package in a clean app | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| APP_DIR="$RUNNER_TEMP/vastlint-react-smoke" | |
| mkdir -p "$APP_DIR" | |
| printf '%s\n' \ | |
| '{' \ | |
| ' "name": "vastlint-react-smoke",' \ | |
| ' "private": true,' \ | |
| ' "type": "module"' \ | |
| '}' \ | |
| > "$APP_DIR/package.json" | |
| pushd "$APP_DIR" >/dev/null | |
| PACKED_TARBALL="$(npm pack "vastlint-react@${VASTLINT_VERSION}" --silent)" | |
| npm install --no-package-lock --ignore-scripts \ | |
| "./$PACKED_TARBALL" \ | |
| react@19.2.0 \ | |
| react-dom@19.2.0 \ | |
| jsdom@26.1.0 | |
| rm "$PACKED_TARBALL" | |
| cat > smoke.mjs <<'EOF' | |
| import React, { act } from 'react'; | |
| import { JSDOM } from 'jsdom'; | |
| import { createRoot } from 'react-dom/client'; | |
| import { createVastSession } from 'vastlint-client'; | |
| import { useVastPlayback } from 'vastlint-react'; | |
| globalThis.IS_REACT_ACT_ENVIRONMENT = true; | |
| function defineGlobal(name, value) { | |
| Object.defineProperty(globalThis, name, { | |
| configurable: true, | |
| writable: true, | |
| value, | |
| }); | |
| } | |
| function installDomGlobals(window) { | |
| defineGlobal('window', window); | |
| defineGlobal('document', window.document); | |
| defineGlobal('navigator', window.navigator); | |
| defineGlobal('HTMLElement', window.HTMLElement); | |
| defineGlobal('Node', window.Node); | |
| defineGlobal('Event', window.Event); | |
| defineGlobal('CustomEvent', window.CustomEvent); | |
| defineGlobal('requestAnimationFrame', (callback) => setTimeout(() => callback(Date.now()), 0)); | |
| defineGlobal('cancelAnimationFrame', (id) => clearTimeout(id)); | |
| } | |
| function createPixelResponse() { | |
| return { | |
| ok: true, | |
| status: 204, | |
| statusText: 'No Content', | |
| async text() { | |
| return ''; | |
| }, | |
| }; | |
| } | |
| const playbackFixture = `<?xml version="1.0" encoding="UTF-8"?> | |
| <VAST version="4.2"> | |
| <Ad id="playback-1"> | |
| <InLine> | |
| <AdSystem>Playback Demo</AdSystem> | |
| <AdTitle>Playback Fixture</AdTitle> | |
| <Impression><![CDATA[https://track.example.com/impression]]></Impression> | |
| <Creatives> | |
| <Creative> | |
| <Linear> | |
| <Duration>00:00:20</Duration> | |
| <TrackingEvents> | |
| <Tracking event="creativeView"><![CDATA[https://track.example.com/creative-view]]></Tracking> | |
| <Tracking event="start"><![CDATA[https://track.example.com/start]]></Tracking> | |
| </TrackingEvents> | |
| <MediaFiles> | |
| <MediaFile delivery="progressive" type="video/mp4" width="1280" height="720"><![CDATA[https://cdn.example.com/video.mp4]]></MediaFile> | |
| </MediaFiles> | |
| </Linear> | |
| </Creative> | |
| </Creatives> | |
| </InLine> | |
| </Ad> | |
| </VAST>`; | |
| const trackingCalls = []; | |
| const dom = new JSDOM('<!doctype html><html><body></body></html>'); | |
| installDomGlobals(dom.window); | |
| async function mountHook(useHook) { | |
| let latestResult = null; | |
| const container = dom.window.document.createElement('div'); | |
| dom.window.document.body.append(container); | |
| const root = createRoot(container); | |
| function Probe() { | |
| latestResult = useHook(); | |
| return null; | |
| } | |
| await act(async () => { | |
| root.render(React.createElement(Probe)); | |
| }); | |
| return { | |
| getLatest() { | |
| if (!latestResult) { | |
| throw new Error('expected hook result to be available'); | |
| } | |
| return latestResult; | |
| }, | |
| async unmount() { | |
| await act(async () => { | |
| root.unmount(); | |
| }); | |
| }, | |
| }; | |
| } | |
| const session = createVastSession({ | |
| source: { kind: 'xml', xml: playbackFixture }, | |
| fetch: async (url) => { | |
| trackingCalls.push(String(url)); | |
| return createPixelResponse(); | |
| }, | |
| }); | |
| const mounted = await mountHook(() => useVastPlayback({ | |
| session, | |
| autoInitialize: false, | |
| mediaSelection: { | |
| supportedMimeTypes: ['video/mp4'], | |
| }, | |
| })); | |
| if (mounted.getLatest().snapshot.status !== 'idle') { | |
| throw new Error('expected hook playback to start idle'); | |
| } | |
| await act(async () => { | |
| await mounted.getLatest().initialize(); | |
| }); | |
| if (mounted.getLatest().snapshot.status !== 'ready') { | |
| throw new Error('expected hook playback to become ready'); | |
| } | |
| if (mounted.getLatest().snapshot.resolvedAd?.adTitle !== 'Playback Fixture') { | |
| throw new Error('expected hook playback to expose resolved ad metadata'); | |
| } | |
| await act(async () => { | |
| await mounted.getLatest().start(); | |
| }); | |
| if (mounted.getLatest().snapshot.status !== 'playing') { | |
| throw new Error('expected hook playback to enter playing state'); | |
| } | |
| if (mounted.getLatest().snapshot.mediaSelection.selected?.url !== 'https://cdn.example.com/video.mp4') { | |
| throw new Error('expected hook playback to expose selected media metadata'); | |
| } | |
| for (const url of [ | |
| 'https://track.example.com/impression', | |
| 'https://track.example.com/creative-view', | |
| 'https://track.example.com/start', | |
| ]) { | |
| if (!trackingCalls.includes(url)) { | |
| throw new Error('expected hook playback tracking call for ' + url); | |
| } | |
| } | |
| await mounted.unmount(); | |
| dom.window.close(); | |
| console.log('vastlint-react smoke passed'); | |
| EOF | |
| node smoke.mjs | |
| popd >/dev/null | |
| smoke-chrome-extension: | |
| name: Smoke Chrome extension build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '20' | |
| package-manager-cache: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # stable | |
| with: | |
| toolchain: stable | |
| targets: wasm32-unknown-unknown | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| - name: Install wasm-pack | |
| run: cargo install wasm-pack --locked | |
| - name: Build WASM payload for extensions | |
| run: | | |
| wasm-pack build crates/vastlint-wasm --target bundler --out-dir ../../npm/pkg | |
| wasm-pack build crates/vastlint-wasm --target nodejs --out-dir ../../npm/pkg-node | |
| - name: Assemble npm package | |
| run: node npm/scripts/assemble.js | |
| - name: Install Chrome extension dependencies | |
| working-directory: chrome | |
| run: npm ci | |
| - name: Build Chrome extension | |
| working-directory: chrome | |
| run: npm run build | |
| - name: Verify Chrome extension dist output | |
| working-directory: chrome | |
| run: | | |
| REQUIRED=( | |
| dist/manifest.json | |
| dist/content.js | |
| dist/service-worker.js | |
| dist/popup.js | |
| dist/popup.html | |
| dist/vastlint_wasm_bg.wasm | |
| ) | |
| MISSING=0 | |
| for f in "${REQUIRED[@]}"; do | |
| if [ ! -f "$f" ]; then | |
| echo "MISSING: $f" | |
| MISSING=$((MISSING + 1)) | |
| else | |
| echo "OK: $f" | |
| fi | |
| done | |
| [ "$MISSING" -eq 0 ] || { echo "$MISSING required file(s) missing from dist/"; exit 1; } | |
| smoke-vscode-vscodium-extension: | |
| name: Smoke VS Code/VSCodium extension package | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '22' | |
| package-manager-cache: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # stable | |
| with: | |
| toolchain: stable | |
| targets: wasm32-unknown-unknown | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| - name: Install wasm-pack | |
| run: cargo install wasm-pack --locked | |
| - name: Build WASM payload for extension npm dependency | |
| run: | | |
| wasm-pack build crates/vastlint-wasm --target bundler --out-dir ../../npm/pkg | |
| wasm-pack build crates/vastlint-wasm --target nodejs --out-dir ../../npm/pkg-node | |
| - name: Assemble npm package | |
| run: node npm/scripts/assemble.js | |
| - name: Install VS Code extension dependencies | |
| working-directory: vscode | |
| run: npm ci | |
| - name: Bundle extension | |
| working-directory: vscode | |
| run: npm run bundle | |
| - name: Package VSIX (usable by VS Code and VSCodium/Open VSX) | |
| working-directory: vscode | |
| run: npx --no-install vsce package --no-update-package-json --out vastlint-smoke.vsix | |
| - name: Verify VSIX contents | |
| working-directory: vscode | |
| run: | | |
| test -s vastlint-smoke.vsix | |
| unzip -l vastlint-smoke.vsix | grep -q 'extension/package.json' | |
| unzip -l vastlint-smoke.vsix | grep -q 'extension/out/extension.js' | |
| smoke-editor-marketplace-install: | |
| name: Smoke editor marketplace installs | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '22' | |
| package-manager-cache: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # stable | |
| with: | |
| toolchain: stable | |
| targets: wasm32-unknown-unknown | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| - name: Install wasm-pack | |
| run: cargo install wasm-pack --locked | |
| - name: Build WASM payload for extension npm dependency | |
| run: | | |
| wasm-pack build crates/vastlint-wasm --target bundler --out-dir ../../npm/pkg | |
| wasm-pack build crates/vastlint-wasm --target nodejs --out-dir ../../npm/pkg-node | |
| - name: Assemble npm package | |
| run: node npm/scripts/assemble.js | |
| - name: Build and package VSIX | |
| working-directory: vscode | |
| run: | | |
| npm ci | |
| npm run bundle | |
| npx --no-install vsce package --no-update-package-json --out vastlint-smoke.vsix | |
| - name: Download portable VS Code and VSCodium | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mkdir -p "$RUNNER_TEMP/editors" | |
| curl -fL "https://update.code.visualstudio.com/latest/linux-x64/stable" -o "$RUNNER_TEMP/editors/vscode.tar.gz" | |
| mkdir -p "$RUNNER_TEMP/editors/vscode" | |
| tar -xzf "$RUNNER_TEMP/editors/vscode.tar.gz" -C "$RUNNER_TEMP/editors/vscode" | |
| echo "VSCODE_BIN=$RUNNER_TEMP/editors/vscode/VSCode-linux-x64/bin/code" >> "$GITHUB_ENV" | |
| CODIUM_URL="$(curl -fsSL https://api.github.com/repos/VSCodium/vscodium/releases/latest | grep browser_download_url | grep 'VSCodium-linux-x64-.*\.tar\.gz' | head -n1 | cut -d '"' -f4)" | |
| if [[ -z "$CODIUM_URL" ]]; then | |
| echo "Could not determine VSCodium release tarball URL" | |
| exit 1 | |
| fi | |
| curl -fL "$CODIUM_URL" -o "$RUNNER_TEMP/editors/vscodium.tar.gz" | |
| mkdir -p "$RUNNER_TEMP/editors/vscodium" | |
| tar -xzf "$RUNNER_TEMP/editors/vscodium.tar.gz" -C "$RUNNER_TEMP/editors/vscodium" | |
| echo "VSCODIUM_BIN=$RUNNER_TEMP/editors/vscodium/bin/codium" >> "$GITHUB_ENV" | |
| - name: Install from VS Code Marketplace in VS Code | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| "$VSCODE_BIN" --user-data-dir "$RUNNER_TEMP/vscode-user" --extensions-dir "$RUNNER_TEMP/vscode-exts" --install-extension aleksUIX.vastlint --force | |
| "$VSCODE_BIN" --user-data-dir "$RUNNER_TEMP/vscode-user" --extensions-dir "$RUNNER_TEMP/vscode-exts" --list-extensions | grep -qi '^aleksuix\.vastlint$' | |
| - name: Install from Open VSX in VSCodium | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| "$VSCODIUM_BIN" --user-data-dir "$RUNNER_TEMP/codium-user" --extensions-dir "$RUNNER_TEMP/codium-exts" --install-extension aleksUIX.vastlint --force | |
| "$VSCODIUM_BIN" --user-data-dir "$RUNNER_TEMP/codium-user" --extensions-dir "$RUNNER_TEMP/codium-exts" --list-extensions | grep -qi '^aleksuix\.vastlint$' | |
| - name: Install local VSIX in both editors | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VSIX_PATH="$GITHUB_WORKSPACE/vscode/vastlint-smoke.vsix" | |
| test -f "$VSIX_PATH" | |
| "$VSCODE_BIN" --user-data-dir "$RUNNER_TEMP/vscode-user-local" --extensions-dir "$RUNNER_TEMP/vscode-exts-local" --install-extension "$VSIX_PATH" --force | |
| "$VSCODE_BIN" --user-data-dir "$RUNNER_TEMP/vscode-user-local" --extensions-dir "$RUNNER_TEMP/vscode-exts-local" --list-extensions | grep -qi '^aleksuix\.vastlint$' | |
| "$VSCODIUM_BIN" --user-data-dir "$RUNNER_TEMP/codium-user-local" --extensions-dir "$RUNNER_TEMP/codium-exts-local" --install-extension "$VSIX_PATH" --force | |
| "$VSCODIUM_BIN" --user-data-dir "$RUNNER_TEMP/codium-user-local" --extensions-dir "$RUNNER_TEMP/codium-exts-local" --list-extensions | grep -qi '^aleksuix\.vastlint$' |