Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
26 changes: 21 additions & 5 deletions .github/workflows/ai-teammate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ jobs:
with:
node-version: '20'

- name: Cache npm global packages
if: vars.AI_AGENT_PROVIDER == 'codemie'
uses: actions/cache@v4
with:
path: |
~/.npm
/usr/local/lib/node_modules
Comment on lines +67 to +73

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caching /usr/local/lib/node_modules without also restoring the global npm bin directory (commonly /usr/local/bin) means the codemie-claude executable may not be present even if the module directory is cached, making the cache ineffective. A more reliable approach is to set an npm global prefix under the workspace/home (e.g., ~/.npm-global) and cache that prefix (bin + lib) so both packages and executables are restored consistently.

Suggested change
- name: Cache npm global packages
if: vars.AI_AGENT_PROVIDER == 'codemie'
uses: actions/cache@v4
with:
path: |
~/.npm
/usr/local/lib/node_modules
- name: Configure npm global prefix
if: vars.AI_AGENT_PROVIDER == 'codemie'
run: |
mkdir -p "${HOME}/.npm-global"
npm config set prefix "${HOME}/.npm-global"
echo "${HOME}/.npm-global/bin" >> "${GITHUB_PATH}"
- name: Cache npm global packages
if: vars.AI_AGENT_PROVIDER == 'codemie'
uses: actions/cache@v4
with:
path: |
~/.npm-global
~/.npm

Copilot uses AI. Check for mistakes.
key: ${{ runner.os }}-npm-global-${{ hashFiles('.github/workflows/ai-teammate.yml') }}
restore-keys: |
${{ runner.os }}-npm-global-

- name: Install Cursor CLI
if: vars.AI_AGENT_PROVIDER != 'codemie'
run: |
Expand Down Expand Up @@ -92,11 +103,16 @@ jobs:
- name: Install Codemie CLI
if: vars.AI_AGENT_PROVIDER == 'codemie'
run: |
echo "📦 Installing Codemie CLI..."
npm install -g @codemieai/code
codemie install claude --supported
echo "✅ Codemie CLI ready"
codemie-claude --version || echo "Version check failed"
if command -v codemie-claude &> /dev/null; then
echo "✅ Codemie CLI found in cache"
codemie-claude --version || echo "Version check failed"
else
Comment on lines +106 to +109

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caching /usr/local/lib/node_modules without also restoring the global npm bin directory (commonly /usr/local/bin) means the codemie-claude executable may not be present even if the module directory is cached, making the cache ineffective. A more reliable approach is to set an npm global prefix under the workspace/home (e.g., ~/.npm-global) and cache that prefix (bin + lib) so both packages and executables are restored consistently.

Copilot uses AI. Check for mistakes.
echo "📦 Installing Codemie CLI..."
npm install -g @codemieai/code
codemie install claude --supported
echo "✅ Codemie CLI ready"
codemie-claude --version || echo "Version check failed"
fi

- name: Install DMTools CLI
run: |
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/deploy-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Build greeting-browser.js
run: |
cd web && npm ci && npm run build
Comment on lines +27 to +34

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deploy workflow installs dependencies on every run without using the built-in npm cache support from actions/setup-node. Adding cache: 'npm' (and cache-dependency-path: web/package-lock.json) can significantly speed up deploy runs while keeping behavior consistent with the unit test workflow.

Copilot uses AI. Check for mistakes.

- name: Setup Pages
uses: actions/configure-pages@v4

Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Unit Tests

on:
pull_request:
branches:
- main
paths:
- 'web/**'
- '.github/workflows/unit-tests.yml'

jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: web
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: web/package-lock.json

- name: Install dependencies
run: npm ci

- name: Run unit tests
run: npm test
84 changes: 84 additions & 0 deletions web/__tests__/greeting.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const fs = require('fs');
const path = require('path');

describe('greeting module', () => {
const greeting = require('../js/greeting.js');

describe('getGreeting', () => {
it('returns "Hello"', () => {
expect(greeting.getGreeting()).toBe('Hello');
});
});

describe('getPageTitle', () => {
it('returns "Hello Jira Diff"', () => {
expect(greeting.getPageTitle()).toBe('Hello Jira Diff');
});

it('includes greeting from getGreeting', () => {
const title = greeting.getPageTitle();
const hello = greeting.getGreeting();
expect(title).toContain(hello);
expect(title).toBe(hello + ' Jira Diff');
});
});

describe('attachToGlobal', () => {
it('attaches getGreeting and getPageTitle to given object', () => {
const globalObj = {};
greeting.attachToGlobal(globalObj);
expect(globalObj.getGreeting()).toBe('Hello');
expect(globalObj.getPageTitle()).toBe('Hello Jira Diff');
});

it('exposes same functions as module exports', () => {
const globalObj = {};
greeting.attachToGlobal(globalObj);
expect(globalObj.getGreeting).toBe(greeting.getGreeting);
expect(globalObj.getPageTitle).toBe(greeting.getPageTitle);
});
});
});

describe('index.html integration', () => {
it('contains greeting script reference', () => {
const htmlPath = path.join(__dirname, '../index.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
expect(html).toContain('js/greeting-browser.js');
});

it('contains getPageTitle call', () => {
const htmlPath = path.join(__dirname, '../index.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
expect(html).toContain('getPageTitle()');
});

it('contains greeting-title element for dynamic content', () => {
const htmlPath = path.join(__dirname, '../index.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
expect(html).toContain('greeting-title');
});
});

describe('greeting-browser.js', () => {
it('contains greeting values from greeting module', () => {
const greeting = require('../js/greeting.js');
const browserPath = path.join(__dirname, '../js/greeting-browser.js');
const browserContent = fs.readFileSync(browserPath, 'utf-8');
expect(browserContent).toContain(JSON.stringify(greeting.getGreeting()));
expect(browserContent).toContain(JSON.stringify(greeting.getPageTitle()));
});
});

describe('build-greeting-browser.js', () => {
it('generates greeting-browser.js with correct content', () => {
const greeting = require('../js/greeting.js');
require('../scripts/build-greeting-browser.js');
const browserPath = path.join(__dirname, '../js/greeting-browser.js');
const browserContent = fs.readFileSync(browserPath, 'utf-8');
expect(browserContent).toContain('window.getGreeting');
expect(browserContent).toContain('window.getPageTitle');
expect(browserContent).toContain(JSON.stringify(greeting.getGreeting()));
expect(browserContent).toContain(JSON.stringify(greeting.getPageTitle()));
});
});
29 changes: 29 additions & 0 deletions web/coverage/clover.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1772095893898" clover="3.2.0">
<project timestamp="1772095893898" name="All files">
<metrics statements="11" coveredstatements="11" conditionals="0" coveredconditionals="0" methods="3" coveredmethods="3" elements="14" coveredelements="14" complexity="0" loc="11" ncloc="11" packages="2" files="2" classes="2"/>
<package name="js">
<metrics statements="5" coveredstatements="5" conditionals="0" coveredconditionals="0" methods="3" coveredmethods="3"/>
<file name="greeting.js" path="/Users/Uladzimir_Klyshevich/git/jira-diff/web/js/greeting.js">
<metrics statements="5" coveredstatements="5" conditionals="0" coveredconditionals="0" methods="3" coveredmethods="3"/>
<line num="6" count="12" type="stmt"/>
<line num="10" count="6" type="stmt"/>
<line num="14" count="2" type="stmt"/>
<line num="15" count="2" type="stmt"/>
<line num="18" count="1" type="stmt"/>
</file>
</package>
<package name="scripts">
<metrics statements="6" coveredstatements="6" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/>
<file name="build-greeting-browser.js" path="/Users/Uladzimir_Klyshevich/git/jira-diff/web/scripts/build-greeting-browser.js">
<metrics statements="6" coveredstatements="6" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/>
<line num="4" count="1" type="stmt"/>
<line num="5" count="1" type="stmt"/>
<line num="7" count="1" type="stmt"/>
<line num="9" count="1" type="stmt"/>
<line num="15" count="1" type="stmt"/>
<line num="16" count="1" type="stmt"/>
</file>
</package>
</project>
</coverage>
3 changes: 3 additions & 0 deletions web/coverage/coverage-final.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{"/Users/Uladzimir_Klyshevich/git/jira-diff/web/js/greeting.js": {"path":"/Users/Uladzimir_Klyshevich/git/jira-diff/web/js/greeting.js","statementMap":{"0":{"start":{"line":6,"column":4},"end":{"line":6,"column":19}},"1":{"start":{"line":10,"column":4},"end":{"line":10,"column":40}},"2":{"start":{"line":14,"column":4},"end":{"line":14,"column":40}},"3":{"start":{"line":15,"column":4},"end":{"line":15,"column":42}},"4":{"start":{"line":18,"column":0},"end":{"line":18,"column":63}}},"fnMap":{"0":{"name":"getGreeting","decl":{"start":{"line":5,"column":9},"end":{"line":5,"column":20}},"loc":{"start":{"line":5,"column":23},"end":{"line":7,"column":1}},"line":5},"1":{"name":"getPageTitle","decl":{"start":{"line":9,"column":9},"end":{"line":9,"column":21}},"loc":{"start":{"line":9,"column":24},"end":{"line":11,"column":1}},"line":9},"2":{"name":"attachToGlobal","decl":{"start":{"line":13,"column":9},"end":{"line":13,"column":23}},"loc":{"start":{"line":13,"column":35},"end":{"line":16,"column":1}},"line":13}},"branchMap":{},"s":{"0":12,"1":6,"2":2,"3":2,"4":1},"f":{"0":12,"1":6,"2":2},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"66ab92495795ebfe7c65b96745b23f8ab9381d27"}
,"/Users/Uladzimir_Klyshevich/git/jira-diff/web/scripts/build-greeting-browser.js": {"path":"/Users/Uladzimir_Klyshevich/git/jira-diff/web/scripts/build-greeting-browser.js","statementMap":{"0":{"start":{"line":4,"column":11},"end":{"line":4,"column":24}},"1":{"start":{"line":5,"column":13},"end":{"line":5,"column":28}},"2":{"start":{"line":7,"column":17},"end":{"line":7,"column":45}},"3":{"start":{"line":9,"column":22},"end":{"line":13,"column":1}},"4":{"start":{"line":15,"column":16},"end":{"line":15,"column":65}},"5":{"start":{"line":16,"column":0},"end":{"line":16,"column":50}}},"fnMap":{},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1},"f":{},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"4a0d0522cba127747ba81dfc7787d591d315a40a"}
}
Loading