diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..6a2b847 --- /dev/null +++ b/action.yml @@ -0,0 +1,41 @@ +name: 'GitGlimpse' +description: 'Auto-generate visual demo clips for UI changes in pull requests' +author: 'git-glimpse' +branding: + icon: 'video' + color: 'purple' + +inputs: + trigger-mode: + description: 'Trigger mode: auto, on-demand, or smart (overrides config file)' + required: false + start-command: + description: 'Command to start the app (overrides config file)' + required: false + preview-url: + description: 'External preview deployment URL (e.g., from Vercel)' + required: false + config-path: + description: 'Path to git-glimpse.config.ts' + default: 'git-glimpse.config.ts' + required: false + format: + description: 'Output format: gif, mp4, or webm' + default: 'gif' + required: false + max-duration: + description: 'Max recording duration in seconds' + default: '30' + required: false + +outputs: + recording-url: + description: 'URL of the uploaded recording artifact' + comment-url: + description: 'URL of the posted PR comment' + success: + description: 'Whether the recording succeeded (true/false)' + +runs: + using: 'node20' + main: 'packages/action/dist/index.js' diff --git a/package.json b/package.json index ca86455..717d902 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,10 @@ "lint": "pnpm -r lint" }, "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/node": "^20.12.0", + "js-yaml": "^4.1.1", "typescript": "^5.4.5", - "vitest": "^1.6.0", - "@types/node": "^20.12.0" + "vitest": "^1.6.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5cdef7..57b90d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,15 @@ importers: .: devDependencies: + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 '@types/node': specifier: ^20.12.0 version: 20.19.37 + js-yaml: + specifier: ^4.1.1 + version: 4.1.1 typescript: specifier: ^5.4.5 version: 5.9.3 @@ -618,6 +624,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} @@ -703,6 +712,9 @@ packages: resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} engines: {node: '>= 14'} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} @@ -1066,6 +1078,10 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + jwt-decode@3.1.2: resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} @@ -2085,6 +2101,8 @@ snapshots: '@types/estree@1.0.8': {} + '@types/js-yaml@4.0.9': {} + '@types/node-fetch@2.6.13': dependencies: '@types/node': 20.19.37 @@ -2196,6 +2214,8 @@ snapshots: - bare-buffer - react-native-b4a + argparse@2.0.1: {} + assertion-error@1.1.0: {} async@3.2.6: {} @@ -2559,6 +2579,10 @@ snapshots: js-tokens@9.0.1: {} + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jwt-decode@3.1.2: {} lazystream@1.0.1: diff --git a/tests/unit/action-yml.test.ts b/tests/unit/action-yml.test.ts new file mode 100644 index 0000000..d550245 --- /dev/null +++ b/tests/unit/action-yml.test.ts @@ -0,0 +1,39 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { load } from 'js-yaml'; + +const root = resolve(__dirname, '../..'); + +function loadActionYml(path: string): any { + return load(readFileSync(path, 'utf8')); +} + +describe('root action.yml', () => { + const rootAction = loadActionYml(resolve(root, 'action.yml')); + const pkgAction = loadActionYml(resolve(root, 'packages/action/action.yml')); + + it('points main to packages/action/dist/index.js', () => { + expect(rootAction.runs.main).toBe('packages/action/dist/index.js'); + }); + + it('uses node20 runtime', () => { + expect(rootAction.runs.using).toBe('node20'); + }); + + it('has the same inputs as packages/action/action.yml', () => { + expect(Object.keys(rootAction.inputs ?? {})).toEqual( + Object.keys(pkgAction.inputs ?? {}) + ); + }); + + it('has the same outputs as packages/action/action.yml', () => { + expect(Object.keys(rootAction.outputs ?? {})).toEqual( + Object.keys(pkgAction.outputs ?? {}) + ); + }); + + it('packages/action/action.yml still uses relative dist path', () => { + expect(pkgAction.runs.main).toBe('dist/index.js'); + }); +});