Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,31 @@ jobs:

build:
needs: [unit-test, integration-test]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# Native builds (npm ci installs correct platform binary)
- os: ubuntu-latest
target: linux-x64
- os: macos-15-intel
target: darwin-x64
- os: macos-latest
target: darwin-arm64
- os: windows-latest
target: win32-x64
# Cross-platform builds (need explicit platform install)
- os: ubuntu-latest
target: linux-arm64
cross: true
cross_cpu: arm64
cross_os: linux
- os: windows-latest
target: win32-arm64
cross: true
cross_cpu: arm64
cross_os: win32
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: read
Expand All @@ -107,18 +131,24 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Install cross-platform sharp binary
if: matrix.cross == true
run: npm install --cpu=${{ matrix.cross_cpu }} --os=${{ matrix.cross_os }} sharp
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Build
run: npm run bundle:prod

- name: Package extension
run: npm run package
run: npx @vscode/vsce package --target ${{ matrix.target }}

- name: Verify VSIX dependencies
run: node scripts/verify-vsix.mjs
run: node scripts/verify-vsix.mjs ${{ matrix.target }}

- name: Upload VSIX artifact
uses: actions/upload-artifact@v4
with:
name: clipshot-vsix
name: clipshot-vsix-${{ matrix.target }}
path: "*.vsix"
retention-days: 7
77 changes: 73 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,33 @@ jobs:
- name: Test
run: npm test

publish:
runs-on: ubuntu-latest
build:
needs: test
strategy:
fail-fast: false
matrix:
include:
# Native builds
- os: ubuntu-latest
target: linux-x64
- os: macos-15-intel
target: darwin-x64
- os: macos-latest
target: darwin-arm64
- os: windows-latest
target: win32-x64
# Cross-platform builds
- os: ubuntu-latest
target: linux-arm64
cross: true
cross_cpu: arm64
cross_os: linux
- os: windows-latest
target: win32-arm64
cross: true
cross_cpu: arm64
cross_os: win32
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: read
Expand All @@ -48,5 +72,50 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish to VS Code Marketplace
run: npx @vscode/vsce publish -p ${{ secrets.VSCE_PAT }}
- name: Install cross-platform sharp binary
if: matrix.cross == true
run: npm install --cpu=${{ matrix.cross_cpu }} --os=${{ matrix.cross_os }} sharp
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Build
run: npm run bundle:prod

- name: Package extension
run: npx @vscode/vsce package --target ${{ matrix.target }}

- name: Upload VSIX artifact
uses: actions/upload-artifact@v4
with:
name: clipshot-vsix-${{ matrix.target }}
path: "*.vsix"
retention-days: 1

publish:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Download all VSIX artifacts
uses: actions/download-artifact@v4
with:
pattern: clipshot-vsix-*
merge-multiple: true

- name: List VSIX files
run: ls -la *.vsix

- name: Publish all platform VSIXs to Marketplace
run: |
for vsix in *.vsix; do
echo "Publishing $vsix..."
npx @vscode/vsce publish --packagePath "$vsix" -p ${{ secrets.VSCE_PAT }}
done
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "clipshot",
"displayName": "ClipShot",
"description": "Paste clipboard images with automatic file saving - perfect for AI chat and documentation",
"version": "0.1.7",
"version": "0.1.8",
"publisher": "kkdev92",
"author": {
"name": "kkdev92",
Expand Down
85 changes: 63 additions & 22 deletions scripts/verify-vsix.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@
* - Automatically reads dependencies from package.json
* - Verifies bundleDependencies matches dependencies
* - Checks all required modules exist in VSIX
* - Tests sharp module can be loaded
* - Supports platform-specific VSIX verification
*
* Run after `npm run package` to validate the VSIX before publishing.
* Usage:
* node scripts/verify-vsix.mjs [target-platform]
*
* Examples:
* node scripts/verify-vsix.mjs # Verify universal or current platform
* node scripts/verify-vsix.mjs win32-arm64 # Verify Windows ARM64 VSIX
* node scripts/verify-vsix.mjs linux-x64 # Verify Linux x64 VSIX
*/

import { execSync } from 'child_process';
Expand All @@ -22,15 +28,23 @@ import { fileURLToPath } from 'url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const projectRoot = resolve(__dirname, '..');

// Platform-specific sharp binaries (at least one should exist)
const PLATFORM_BINARIES = [
'node_modules/@img/sharp-win32-x64',
'node_modules/@img/sharp-win32-arm64',
'node_modules/@img/sharp-linux-x64',
'node_modules/@img/sharp-linux-arm64',
'node_modules/@img/sharp-darwin-x64',
'node_modules/@img/sharp-darwin-arm64',
];
// Target platform from command line argument
const targetPlatform = process.argv[2] || null;

// Map vsce target to sharp @img package name
const TARGET_TO_SHARP_BINARY = {
'win32-x64': '@img/sharp-win32-x64',
'win32-arm64': '@img/sharp-win32-arm64',
'linux-x64': '@img/sharp-linux-x64',
'linux-arm64': '@img/sharp-linux-arm64',
'darwin-x64': '@img/sharp-darwin-x64',
'darwin-arm64': '@img/sharp-darwin-arm64',
};

// All platform-specific sharp binaries
const ALL_PLATFORM_BINARIES = Object.values(TARGET_TO_SHARP_BINARY).map(
pkg => `node_modules/${pkg}`
);

// Known transitive dependencies that must be included
// Add entries here for dependencies that have important transitive deps
Expand All @@ -48,7 +62,17 @@ function findVsixFile() {
if (files.length === 0) {
throw new Error('No .vsix file found. Run "npm run package" first.');
}
// Return the first one (usually there's only one)

// If target platform specified, look for platform-specific VSIX
if (targetPlatform) {
const platformVsix = files.find(f => f.includes(`@${targetPlatform}`));
if (platformVsix) {
return join(projectRoot, platformVsix);
}
// Fall back to first VSIX if platform-specific not found
console.log(` Note: No VSIX with @${targetPlatform} found, using ${files[0]}`);
}

return join(projectRoot, files[0]);
}

Expand Down Expand Up @@ -125,20 +149,36 @@ function verifyModulesInVsix(extractDir, pkg) {
// Check platform binaries for sharp
if (dependencies.includes('sharp')) {
console.log('\nVerifying sharp platform binaries...\n');
const foundBinaries = [];
for (const binaryPath of PLATFORM_BINARIES) {

if (targetPlatform && TARGET_TO_SHARP_BINARY[targetPlatform]) {
// Platform-specific VSIX: check only the required binary
const expectedBinary = TARGET_TO_SHARP_BINARY[targetPlatform];
const binaryPath = `node_modules/${expectedBinary}`;
const fullPath = join(extensionDir, binaryPath);

if (existsSync(fullPath)) {
console.log(` ✓ ${binaryPath}`);
foundBinaries.push(binaryPath);
console.log(` ✓ ${binaryPath} (required for ${targetPlatform})`);
} else {
console.log(` ✗ ${binaryPath}: MISSING (required for ${targetPlatform})`);
errors.push(`Missing platform binary for ${targetPlatform}: ${expectedBinary}`);
}
}

if (foundBinaries.length === 0) {
errors.push('No platform-specific sharp binaries found (@img/sharp-*)');
console.log(' ✗ No platform binaries found');
} else {
console.log(`\n Found ${foundBinaries.length} platform binary package(s)`);
// Universal VSIX or unknown target: check for any binary
const foundBinaries = [];
for (const binaryPath of ALL_PLATFORM_BINARIES) {
const fullPath = join(extensionDir, binaryPath);
if (existsSync(fullPath)) {
console.log(` ✓ ${binaryPath}`);
foundBinaries.push(binaryPath);
}
}

if (foundBinaries.length === 0) {
errors.push('No platform-specific sharp binaries found (@img/sharp-*)');
console.log(' ✗ No platform binaries found');
} else {
console.log(`\n Found ${foundBinaries.length} platform binary package(s)`);
}
}
}

Expand Down Expand Up @@ -191,6 +231,7 @@ async function main() {
// Load package.json
const pkg = loadPackageJson();
console.log(`\nPackage: ${pkg.name}@${pkg.version}`);
console.log(`Target: ${targetPlatform || 'universal'}`);
console.log(`Dependencies: ${Object.keys(pkg.dependencies || {}).join(', ')}`);

// Step 1: Verify bundleDependencies configuration
Expand Down