Skip to content
Merged
37 changes: 29 additions & 8 deletions .github/scripts/ciScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,36 @@ module.exports = async ({ github, context, core }) => {
}
});

console.log({
backendFiles,
mobileFiles,
webFiles
});
console.log({
backendFiles,
mobileFiles,
webFiles
});

core.setOutput(
"backendFiles",
backendFiles
.map(file => file.replace("apps/backend/", ""))
.join(" ")
)

core.setOutput(
"mobileFiles",
mobileFiles
.map(file => file.replace("apps/mobile/", ""))
.join(" ")
)

core.setOutput(
"webFiles",
webFiles
.map(file => file.replace("apps/web/", ""))
.join(" ")
)

core.setOutput("backendChanged",backendFiles.length > 0)
core.setOutput("mobileChanged",mobileFiles.length > 0)
core.setOutput("webChanged",webFiles.length > 0)
core.setOutput("backendChanged", backendFiles.length > 0)
core.setOutput("mobileChanged", mobileFiles.length > 0)
core.setOutput("webChanged", webFiles.length > 0)

} catch (error) {
console.error(error);
Expand Down
98 changes: 58 additions & 40 deletions .github/scripts/commentResults.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,101 @@
module.exports = async ({ github, context, backend, mobile, web }) => {
module.exports = async ({
github,
context,
backend,
mobile,
web,
backendLint,
backendTest,
backendTypecheck,
mobileLint,
mobileTest,
webCheck,
webBuild
}) => {
const owner = context.repo.owner;
const repo = context.repo.repo;
const pr = context.payload.pull_request;
const prNumber = pr.number;
const prNumber = context.payload.pull_request.number;

const statusEmoji = (status) => {
const emoji = (status) => {
if (status === 'success') return '✅';
if (status === 'failure') return '❌';
if (status === 'skipped') return '⏭️';
return '⚪';
};

const statusLabel = (status) => {
if (status === 'skipped') return `${statusEmoji(status)} Skipped — no changes detected`;
return `${statusEmoji(status)} ${status}`;
const label = (status) => {
if (!status) return '⚪ unknown';
return `${emoji(status)} ${status}`;
};

const results = [backend, mobile, web];
const allSkipped = results.every((s) => s === 'skipped');
const anyFailure = results.some((s) => s === 'failure');
const allPassed = results.every((s) => s === 'success' || s === 'skipped');
const anyFailure = [
backend,
mobile,
web
].includes('failure');

let title;
if (allSkipped) {
title = '⏭️ No changes detected — all checks skipped';
} else if (anyFailure) {
title = '❌ Some checks failed';
} else if (allPassed) {
title = '✅ All checks passed';
} else {
title = '⚪ Checks completed';
}
const title = anyFailure
? '❌ Some checks failed'
: '✅ CI completed';

const timestamp = new Date().toUTCString();

const body = `## CI Results — ${title}

### 🖥️ Backend (${label(backend)})
| Check | Status |
|---|---|
| 🖥️ Backend | ${statusLabel(backend)} |
| 📱 Mobile | ${statusLabel(mobile)} |
| 🌐 Web | ${statusLabel(web)} |
| Lint | ${label(backendLint)} |
| Test | ${label(backendTest)} |
| Typecheck | ${label(backendTypecheck)} |

> ⏭️ **Skipped** means no files were changed in that area — the check was not needed.
### 📱 Mobile (${label(mobile)})
| Check | Status |
|---|---|
| Lint | ${label(mobileLint)} |
| Test | ${label(mobileTest)} |

### 🌐 Web (${label(web)})
| Check | Status |
|---|---|
| Check | ${label(webCheck)} |
| Build | ${label(webBuild)} |

---
🕐 Last updated: \`${timestamp}\``;

const COMMENT_MARKER = '## CI Results —';

try {
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number: prNumber,
});
const comments = await github.paginate(
github.rest.issues.listComments,
{
owner,
repo,
issue_number: prNumber
}
);

const existingComment = comments.find(
(c) => c.body && c.body.startsWith(COMMENT_MARKER)
const existing = comments.find(
c => c.body && c.body.startsWith(COMMENT_MARKER)
);

if (existingComment) {
if (existing) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existingComment.id,
body,
comment_id: existing.id,
body
});
console.log(`Updated existing comment: ${existingComment.id}`);
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body,
body
});
console.log('Created new CI results comment');
}
} catch (error) {
console.error('Failed to post comment:', error);
} catch (err) {
console.error(err);
}
};
51 changes: 37 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ jobs:
backendChanged: ${{ steps.detect.outputs.backendChanged }}
mobileChanged: ${{ steps.detect.outputs.mobileChanged }}
webChanged: ${{ steps.detect.outputs.webChanged }}
backendFiles: ${{ steps.detect.outputs.backendFiles }}
mobileFiles: ${{ steps.detect.outputs.mobileFiles }}
webFiles: ${{ steps.detect.outputs.webFiles }}

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Detect changed files
id: detect
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
Expand All @@ -44,9 +46,18 @@ jobs:
- uses: pnpm/action-setup@v6.0.8

- run: pnpm install
- run: cd apps/backend && pnpm lint
- run: cd apps/backend && pnpm test
- run: cd apps/backend && pnpm typecheck

- name: Backend lint
id: backend_lint
run: cd apps/backend && pnpm eslint ${{ needs.detect-changes.outputs.backendFiles }}

- name: Backend test
id: backend_test
run: cd apps/backend && pnpm test ${{ needs.detect-changes.outputs.backendFiles }}

- name: Backend typecheck
id: backend_typecheck
run: cd apps/backend && pnpm typecheck ${{ needs.detect-changes.outputs.backendFiles }}

web-ci:
needs: detect-changes
Expand All @@ -63,8 +74,14 @@ jobs:
- uses: pnpm/action-setup@v6.0.8

- run: pnpm install
- run: cd apps/web && pnpm check
- run: cd apps/web && pnpm build

- name: Web check
id: web_check
run: cd apps/web && pnpm check

- name: Web build
id: web_build
run: cd apps/web && pnpm build

mobile-ci:
needs: detect-changes
Expand All @@ -81,8 +98,14 @@ jobs:
- uses: pnpm/action-setup@v6.0.8

- run: pnpm install
- run: cd apps/mobile && pnpm lint
- run: cd apps/mobile && pnpm test

- name: Mobile lint
id: mobile_lint
run: cd apps/mobile && pnpm eslint ${{ needs.detect-changes.outputs.mobileFiles }}

- name: Mobile test
id: mobile_test
run: cd apps/mobile && pnpm test

comment-results:
needs:
Expand All @@ -93,19 +116,19 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Comment results
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const script = require('./.github/scripts/commentResults.js');
await script({

await script({
github,
context,
backend: '${{ needs.backend-ci.result }}',
web: '${{ needs.web-ci.result }}',
mobile: '${{ needs.mobile-ci.result }}'
});
});