@lightningjs/blits 1.27.1 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,144 +8,94 @@ on:
8
8
 
9
9
  jobs:
10
10
  comment-lint-results:
11
- # Only run this job if the previous workflow failed (indicating lint errors)
12
11
  if: github.event.workflow_run.conclusion == 'failure'
13
12
  runs-on: ubuntu-latest
14
13
  permissions:
15
14
  pull-requests: write
16
15
 
17
16
  steps:
18
- - name: Download Lint Results
19
- id: download
20
- uses: actions/github-script@v6
21
- with:
22
- script: |
23
- try {
24
- core.info('Downloading lint results artifact');
17
+ - name: Download Lint Results
18
+ id: download
19
+ uses: actions/github-script@v6
20
+ with:
21
+ result-encoding: string
22
+ script: |
25
23
 
26
- const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
27
- owner: context.repo.owner,
28
- repo: context.repo.repo,
29
- run_id: ${{ github.event.workflow_run.id }}
30
- });
31
-
32
- const matchArtifact = artifacts.data.artifacts.find(artifact => artifact.name === "lint-results");
33
- if (!matchArtifact) {
34
- core.setFailed('No lint results artifact found');
35
- return false;
36
- }
37
-
38
- core.info(`Found artifact id: ${matchArtifact.id}`);
39
-
40
- const download = await github.rest.actions.downloadArtifact({
41
- owner: context.repo.owner,
42
- repo: context.repo.repo,
43
- artifact_id: matchArtifact.id,
44
- archive_format: 'zip'
45
- });
46
-
47
- const fs = require('fs');
48
24
  try {
49
- fs.writeFileSync('lint-results.zip', Buffer.from(download.data));
50
- core.info('Successfully downloaded and saved artifact');
51
- return true;
52
- } catch (error) {
53
- core.setFailed(`Failed to write artifact: ${error.message}`);
54
- return false;
25
+ core.info('Downloading lint-results artifact');
26
+ const runId = context.payload.workflow_run.id;
27
+
28
+ const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
29
+ owner: context.repo.owner,
30
+ repo: context.repo.repo,
31
+ run_id: runId
32
+ });
33
+
34
+ const art = artifacts.data.artifacts.find(a => a.name === "lint-results");
35
+ if (!art) {
36
+ core.setFailed('No lint-results artifact found');
37
+ return 'false';
38
+ }
39
+
40
+ core.info(`Found artifact id ${art.id}, downloading…`);
41
+ const dl = await github.rest.actions.downloadArtifact({
42
+ owner: context.repo.owner,
43
+ repo: context.repo.repo,
44
+ artifact_id: art.id,
45
+ archive_format: 'zip'
46
+ });
47
+
48
+ require('fs').writeFileSync('lint-results.zip', Buffer.from(dl.data));
49
+ core.info('Downloaded and saved lint-results.zip');
50
+ return 'true';
51
+
52
+ } catch (err) {
53
+ core.setFailed(`Download failed: ${err.message}`);
54
+ return 'false';
55
55
  }
56
- } catch (error) {
57
- core.setFailed(`Failed to download artifact: ${error.message}`);
58
- return false;
59
- }
60
- result-encoding: string
61
-
62
- - name: Extract Lint Results
63
- if: steps.download.outputs.result == 'true'
64
- id: extract
65
- run: |
66
- mkdir -p lint-results
67
- unzip -o lint-results.zip -d lint-results
68
56
 
69
- if [ -f lint-results/errors.md ]; then
70
- # Use GitHub's EOF syntax for multiline content
71
- echo "LINT_ERRORS<<EOF" >> $GITHUB_ENV
72
- cat lint-results/errors.md >> $GITHUB_ENV
73
- echo "EOF" >> $GITHUB_ENV
74
- echo "HAS_ERRORS=true" >> $GITHUB_OUTPUT
75
- else
76
- echo "HAS_ERRORS=false" >> $GITHUB_OUTPUT
77
- fi
78
-
79
- - name: Find PR Number
80
- if: steps.extract.outputs.HAS_ERRORS == 'true'
81
- id: find-pr
82
- uses: actions/github-script@v6
83
- with:
84
- script: |
85
- try {
86
- core.info('Finding associated PR');
87
-
88
- const { owner, repo } = context.repo;
89
- const run_id = ${{ github.event.workflow_run.id }};
90
-
91
- // Get the triggering workflow run
92
- const run = await github.rest.actions.getWorkflowRun({
93
- owner,
94
- repo,
95
- run_id
96
- });
97
-
98
- // Find associated PR - first try the event payload
99
- if (run.data.pull_requests && run.data.pull_requests.length > 0) {
100
- core.info(`Found PR directly from run data: #${run.data.pull_requests[0].number}`);
101
- return run.data.pull_requests[0].number;
102
- }
103
-
104
- // Fallback to searching by head SHA
105
- core.info(`Searching for PR using head SHA: ${run.data.head_sha}`);
106
- const pulls = await github.rest.pulls.list({
107
- owner,
108
- repo,
109
- state: 'open',
110
- head: `${owner}:${run.data.head_branch}`
111
- });
112
-
113
- if (pulls.data.length > 0) {
114
- core.info(`Found PR by branch: #${pulls.data[0].number}`);
115
- return pulls.data[0].number;
116
- }
117
-
118
- core.info('No PR found for this workflow run');
119
- return null;
120
- } catch (error) {
121
- core.setFailed(`Failed to find PR: ${error.message}`);
122
- return null;
123
- }
124
- result-encoding: string
125
-
126
- - name: Post Lint Results as PR Comment
127
- if: steps.find-pr.outputs.result != 'null' && steps.find-pr.outputs.result != ''
128
- uses: actions/github-script@v6
129
- with:
130
- script: |
131
- try {
132
- const pr_number = parseInt(${{ steps.find-pr.outputs.result }});
133
-
134
- if (isNaN(pr_number)) {
135
- core.warning('Invalid PR number');
136
- return;
57
+ - name: Extract Lint Results
58
+ if: steps.download.outputs.result == 'true'
59
+ id: extract
60
+ run: |
61
+ mkdir -p lint-results
62
+ unzip -o lint-results.zip -d lint-results
63
+
64
+ if [ -f lint-results/errors.md ]; then
65
+ echo "LINT_ERRORS<<EOF" >> $GITHUB_ENV
66
+ cat lint-results/errors.md >> $GITHUB_ENV
67
+ echo "EOF" >> $GITHUB_ENV
68
+ echo "HAS_ERRORS=true" >> $GITHUB_OUTPUT
69
+ else
70
+ echo "HAS_ERRORS=false" >> $GITHUB_OUTPUT
71
+ fi
72
+
73
+ - name: Post Lint Results as PR Comment
74
+ if: steps.extract.outputs.HAS_ERRORS == 'true'
75
+ uses: actions/github-script@v6
76
+ with:
77
+ script: |
78
+ try {
79
+ const pulls = context.payload.workflow_run.pull_requests;
80
+ core.info(`Found ${pulls.length} triggering PR(s)`);
81
+
82
+ if (pulls.length === 0) {
83
+ core.warning('No associated PRs; skipping comment.');
84
+ return;
85
+ }
86
+
87
+ const body = process.env.LINT_ERRORS;
88
+ for (const pr of pulls) {
89
+ core.info(`Commenting lint errors on PR #${pr.number}`);
90
+ await github.rest.issues.createComment({
91
+ owner: context.repo.owner,
92
+ repo: context.repo.repo,
93
+ issue_number: pr.number,
94
+ body
95
+ });
96
+ }
97
+ core.info('All comments posted');
98
+ } catch (err) {
99
+ core.error('Failed to post lint comment:', err);
100
+ core.setFailed(err.message);
137
101
  }
138
-
139
- core.info(`Posting comment to PR #${pr_number}`);
140
-
141
- await github.rest.issues.createComment({
142
- owner: context.repo.owner,
143
- repo: context.repo.repo,
144
- issue_number: pr_number,
145
- body: process.env.LINT_ERRORS
146
- });
147
-
148
- core.info(`Successfully posted lint errors comment to PR #${pr_number}`);
149
- } catch (error) {
150
- core.setFailed(`Failed to post comment: ${error.message}`);
151
- }
@@ -3,8 +3,7 @@ name: Comment Test Results
3
3
  on:
4
4
  workflow_run:
5
5
  workflows: ["Run Blits Tests"]
6
- types:
7
- - completed
6
+ types: [completed]
8
7
 
9
8
  jobs:
10
9
  comment-test-results:
@@ -13,102 +12,70 @@ jobs:
13
12
  pull-requests: write
14
13
 
15
14
  steps:
16
- - name: Download Test Results
17
- uses: actions/github-script@v6
18
- with:
19
- script: |
20
- const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
21
- owner: context.repo.owner,
22
- repo: context.repo.repo,
23
- run_id: ${{ github.event.workflow_run.id }}
24
- });
25
-
26
- const matchArtifact = artifacts.data.artifacts.find(artifact => artifact.name === "test-results");
27
- if (!matchArtifact) {
28
- core.setFailed('No test results artifact found');
29
- return;
30
- }
31
-
32
- const download = await github.rest.actions.downloadArtifact({
33
- owner: context.repo.owner,
34
- repo: context.repo.repo,
35
- artifact_id: matchArtifact.id,
36
- archive_format: 'zip'
37
- });
38
-
39
- const fs = require('fs');
40
- fs.writeFileSync('test-results.zip', Buffer.from(download.data));
41
-
42
- - name: Extract Test Results
43
- run: |
44
- mkdir -p test-results
45
- unzip -o test-results.zip -d test-results
46
-
47
- TIMESTAMP=$(cat test-results/timestamp.txt)
48
- SUMMARY=$(cat test-results/summary.txt)
49
- FAILED=$(cat test-results/failed.txt)
50
-
51
- echo "TIMESTAMP=$TIMESTAMP" >> $GITHUB_ENV
52
- echo "SUMMARY=$SUMMARY" >> $GITHUB_ENV
53
- echo "FAILED=$FAILED" >> $GITHUB_ENV
54
-
55
- # Check if error.txt exists and read it if it does
56
- if [ -f test-results/error.txt ]; then
57
- # Store raw error output in a file for the next step
58
- cat test-results/error.txt > raw_error.txt
59
- fi
60
-
61
- - name: Find PR Number
62
- id: find-pr
63
- uses: actions/github-script@v6
64
- with:
65
- script: |
66
- const { owner, repo } = context.repo;
67
- const run_id = ${{ github.event.workflow_run.id }};
68
-
69
- // Get the triggering workflow run
70
- const run = await github.rest.actions.getWorkflowRun({
71
- owner,
72
- repo,
73
- run_id
74
- });
75
-
76
- // Find associated PR
77
- const pulls = await github.rest.pulls.list({
78
- owner,
79
- repo,
80
- state: 'open',
81
- head: run.data.head_sha
82
- });
83
-
84
- if (pulls.data.length > 0) {
85
- return pulls.data[0].number;
86
- }
87
-
88
- console.log('No PR found');
89
- return null;
90
- result-encoding: string
91
-
92
- - name: Post Test Results as PR Comment
93
- if: steps.find-pr.outputs.result != 'null'
94
- uses: actions/github-script@v6
95
- with:
96
- script: |
97
- const fs = require('fs');
98
- const pr_number = parseInt(${{ steps.find-pr.outputs.result }});
99
- const status = process.env.FAILED === 'true' ? '❌ FAILED' : '✅ PASSED';
100
-
101
- let commentBody = `#### Test Results: ${status}\n**Run at:** ${process.env.TIMESTAMP}\n\n**Summary:**\n${process.env.SUMMARY}`;
102
-
103
- // Add error output if it exists
104
- if (fs.existsSync('raw_error.txt')) {
105
- const errorOutput = fs.readFileSync('raw_error.txt', 'utf8');
106
- commentBody += '\n\n**Error Output:**\n```\n' + errorOutput + '\n```';
107
- }
108
-
109
- github.rest.issues.createComment({
110
- owner: context.repo.owner,
111
- repo: context.repo.repo,
112
- issue_number: pr_number,
113
- body: commentBody
114
- });
15
+ - name: Download Test Results
16
+ uses: actions/github-script@v6
17
+ with:
18
+ script: |
19
+ const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
20
+ owner: context.repo.owner,
21
+ repo: context.repo.repo,
22
+ run_id: ${{ github.event.workflow_run.id }}
23
+ });
24
+ const art = artifacts.data.artifacts.find(a => a.name === "test-results");
25
+ if (!art) core.setFailed('No test-results artifact found');
26
+ const dl = await github.rest.actions.downloadArtifact({
27
+ owner: context.repo.owner,
28
+ repo: context.repo.repo,
29
+ artifact_id: art.id,
30
+ archive_format: 'zip'
31
+ });
32
+ require('fs').writeFileSync('test-results.zip', Buffer.from(dl.data));
33
+ - name: Extract Test Results
34
+ run: |
35
+ mkdir -p test-results
36
+ unzip -o test-results.zip -d test-results
37
+ echo "TIMESTAMP=$(cat test-results/timestamp.txt)" >> $GITHUB_ENV
38
+ echo "SUMMARY=$(cat test-results/summary.txt)" >> $GITHUB_ENV
39
+ echo "FAILED=$(cat test-results/failed.txt)" >> $GITHUB_ENV
40
+ if [ -f test-results/error.txt ]; then cp test-results/error.txt raw_error.txt; fi
41
+
42
+ - name: Post Test Results as PR Comment
43
+ uses: actions/github-script@v6
44
+ with:
45
+ script: |
46
+ const fs = require('fs');
47
+
48
+ try {
49
+ const pulls = context.payload.workflow_run.pull_requests;
50
+ console.log(`Found ${pulls.length} triggering PR(s).`);
51
+
52
+ if (pulls.length === 0) {
53
+ console.warn('No pull requests found for this workflow run; skipping comment.');
54
+ return;
55
+ }
56
+
57
+ const status = process.env.FAILED === 'true' ? '❌ FAILED' : '✅ PASSED';
58
+ let commentBody = `#### Test Results: ${status}\n`
59
+ + `**Run at:** ${process.env.TIMESTAMP}\n\n`
60
+ + `**Summary:**\n${process.env.SUMMARY}`;
61
+
62
+ if (fs.existsSync('raw_error.txt')) {
63
+ commentBody += '\n\n**Error Output:**\n```\n'
64
+ + fs.readFileSync('raw_error.txt', 'utf8')
65
+ + '\n```';
66
+ }
67
+
68
+ for (const pr of pulls) {
69
+ console.log(`Commenting on PR #${pr.number}`);
70
+ await github.rest.issues.createComment({
71
+ owner: context.repo.owner,
72
+ repo: context.repo.repo,
73
+ issue_number: pr.number,
74
+ body: commentBody
75
+ });
76
+ }
77
+
78
+ } catch (err) {
79
+ console.error('🛑 Failed to post test results comment:', err);
80
+ core.setFailed(`Comment step failed: ${err.message}`);
81
+ }
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  _15 apr 2025_
4
4
 
5
+ ## v1.28.0
6
+
7
+ - Added graceful handling of announcer when speechSynthesis API is not available
8
+ - Renamed `beforeAll` method on router to `beforeEach` (as specified in the type definitions)
9
+ - Fixed detection of correct PR to comment for github workflows
10
+
11
+ _15 apr 2025_
12
+
5
13
  ## v1.27.1
6
14
 
7
15
  - Fixed issue with global watcher on router state not being cleared out
package/index.d.ts CHANGED
@@ -23,7 +23,7 @@ import {type ShaderEffect as RendererShaderEffect, type WebGlCoreShader, type Re
23
23
  declare module '@lightningjs/blits' {
24
24
 
25
25
 
26
- export interface AnnouncerUtterance extends Promise {
26
+ export interface AnnouncerUtterance extends Promise<T> {
27
27
  /**
28
28
  * Removes a specific message from the announcement queue,
29
29
  * to make sure it isn't spoke out.
@@ -481,7 +481,7 @@ declare module '@lightningjs/blits' {
481
481
  }
482
482
 
483
483
  export interface RouterHooks {
484
- beforeEach?: (to: Route, from: Route) => string | Route | Promise<string | Route>;
484
+ beforeEach?: (to: Route, from: Route) => string | Route | Promise<string | Route> | void;
485
485
  }
486
486
 
487
487
  export interface RouterConfig {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightningjs/blits",
3
- "version": "1.27.1",
3
+ "version": "1.28.0",
4
4
  "description": "Blits: The Lightning 3 App Development Framework",
5
5
  "bin": "bin/index.js",
6
6
  "exports": {
@@ -15,6 +15,8 @@
15
15
  * SPDX-License-Identifier: Apache-2.0
16
16
  */
17
17
 
18
+ import { Log } from '../lib/log.js'
19
+
18
20
  const syn = window.speechSynthesis
19
21
 
20
22
  const isAndroid = /android/i.test((window.navigator || {}).userAgent || '')
@@ -82,14 +84,21 @@ const speak = (options) => {
82
84
 
83
85
  export default {
84
86
  speak(options) {
85
- if (!initialized) {
86
- initialize()
87
+ if (syn !== undefined) {
88
+ if (initialized === false) {
89
+ initialize()
90
+ }
91
+ return speak(options)
92
+ } else {
93
+ Log.error('speechSynthesis web API not available')
94
+ return Promise.reject({ error: 'unavailable' })
87
95
  }
88
- return speak(options)
89
96
  },
90
97
  cancel() {
91
- syn.cancel()
92
- clear()
98
+ if (syn !== undefined) {
99
+ syn.cancel()
100
+ clear()
101
+ }
93
102
  },
94
103
  // @todo
95
104
  // getVoices() {
@@ -148,8 +148,8 @@ export const navigate = async function () {
148
148
  let beforeEachResult
149
149
  if (this.parent[symbols.routerHooks]) {
150
150
  const hooks = this.parent[symbols.routerHooks]
151
- if (hooks.beforeAll) {
152
- beforeEachResult = await hooks.beforeAll(route, previousRoute)
151
+ if (hooks.beforeEach) {
152
+ beforeEachResult = await hooks.beforeEach(route, previousRoute)
153
153
  if (isString(beforeEachResult)) {
154
154
  to(beforeEachResult)
155
155
  return