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
4 changes: 3 additions & 1 deletion cli/src/execDocker/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Docker from 'dockerode';
import os from 'os';
import { readdir } from 'fs/promises';
import { createSigintAbortSignal } from '../utils/abortController.js';
import { CONFIG_FILE } from '../config/config.js';

type ProgressEvent = { stream?: string };
type FinishOutputRow = { error?: string };
Expand Down Expand Up @@ -31,9 +32,10 @@ export async function dockerBuild({
const osType = os.type();

const contextPath = process.cwd(); // Use current working directory
const contextFiles = await readdir(contextPath);
const buildArgs = {
context: contextPath,
src: await readdir(contextPath), // Include all files of the context
src: contextFiles.filter((fileName) => fileName !== CONFIG_FILE), // exclude config file from build context even if not in dockerignore
};

// by default force to build amd64 image which is architecture used in iExec workers
Expand Down
5 changes: 5 additions & 0 deletions cli/templates/JavaScript/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
################ IMPORTANT NOTICE ###################
# Do not modify this file #
# Any modifications might not be taken into account #
#####################################################

# iapp config file may contain secrets
iapp.config.json

Expand Down
2 changes: 1 addition & 1 deletion cli/templates/JavaScript/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ FROM node:22-alpine3.21
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
COPY src/ ./src/
ENTRYPOINT ["node", "--disable-wasm-trap-handler", "/app/src/app.js"]
5 changes: 5 additions & 0 deletions cli/templates/Python3.13/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
################ IMPORTANT NOTICE ###################
# Do not modify this file #
# Any modifications might not be taken into account #
#####################################################

# iapp config file may contain secrets
iapp.config.json

Expand Down
2 changes: 1 addition & 1 deletion cli/templates/Python3.13/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ FROM python:3.13.3-alpine3.21
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
COPY src/ ./src/
ENTRYPOINT ["python3", "/app/src/app.py"]
100 changes: 92 additions & 8 deletions cli/test/iapp.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { test, beforeEach, after, afterEach, describe } from 'node:test';
import { join } from 'node:path';
import { dirname, join } from 'node:path';
import assert from 'node:assert/strict';
import { render, cleanup } from 'cli-testing-library';
import {
Expand All @@ -10,6 +10,8 @@ import {
removeTestDir,
retry,
} from './test-utils.ts';
import { fileURLToPath } from 'node:url';
import { readFile, rm, writeFile } from 'node:fs/promises';

// Final cleanup code after all tests
after(async () => {
Expand Down Expand Up @@ -42,10 +44,16 @@ test('iapp help command works', async () => {
});

test('iapp -v command works', async () => {
const __dirname = dirname(fileURLToPath(import.meta.url));
const packageJson = JSON.parse(
await readFile(join(__dirname, '../package.json'), 'utf-8')
);
const { version } = packageJson;

const { findByText, debug, clear } = await render(IAPP_COMMAND, ['-v'], {
cwd: testDir,
});
await findByText('1.3.3');
await findByText(version);
// debug();
clear();
});
Expand Down Expand Up @@ -123,8 +131,6 @@ describe('JavaScript iApp', () => {
await checkDockerImageContent({
dockerImageId,
expectedFiles: [
'Dockerfile',
'README.md',
'node_modules',
'package-lock.json',
'package.json',
Expand Down Expand Up @@ -194,8 +200,6 @@ describe('JavaScript iApp', () => {
await checkDockerImageContent({
dockerImageId,
expectedFiles: [
'Dockerfile',
'README.md',
'node_modules',
'package-lock.json',
'package.json',
Expand Down Expand Up @@ -254,7 +258,7 @@ describe('Python iApp', () => {
// check built docker image content
await checkDockerImageContent({
dockerImageId,
expectedFiles: ['Dockerfile', 'README.md', 'requirements.txt', 'src'],
expectedFiles: ['requirements.txt', 'src'],
});
});
});
Expand Down Expand Up @@ -318,8 +322,88 @@ describe('Python iApp', () => {
// check built docker image content
await checkDockerImageContent({
dockerImageId,
expectedFiles: ['Dockerfile', 'README.md', 'requirements.txt', 'src'],
expectedFiles: ['requirements.txt', 'src'],
});
});
});
});
});

describe('Custom app', () => {
describe('iapp test', () => {
const projectName = 'test-iapp';

// Initialize a test iApp project before each test
beforeEach(async () => {
await initIappProject({
testDir,
projectName,
template: 'JavaScript',
projectType: 'Hello World',
});
});

test('iapp test command works', async () => {
// removed .dockerignore
await rm(join(testDir, projectName, '.dockerignore'));
// changed Dockerfile to a custom one
const dockerfileContent = await readFile(
join(testDir, projectName, 'Dockerfile'),
'utf-8'
);
const customDockerfileContent = dockerfileContent.replace(
'COPY src/ ./src/',
'COPY . ./'
);
await writeFile(
join(testDir, projectName, 'Dockerfile'),
customDockerfileContent,
'utf-8'
);

const { findByText, debug, clear, userEvent, getStdallStr } =
await render(IAPP_COMMAND, ['test'], {
cwd: join(testDir, projectName),
});
// wait for docker build and test run
await retry(() => findByText('Would you like to see the app logs?'), {
retries: 8,
delay: 3000,
});
// extract docker image id from stdout
const std = getStdallStr();
const dockerImageIdMatch = std.match(
/App docker image built \(sha256:[a-f0-9]{64}\)/
);
assert.ok(dockerImageIdMatch, 'Docker image ID not found in output');
const dockerImageId = dockerImageIdMatch![0].split('(')[1].slice(0, -1);

// debug();
clear();
userEvent.keyboard('n');
await findByText('Would you like to see the result?');
// debug();
clear();
userEvent.keyboard('n');
await findByText('When ready run iapp deploy');
// debug();
clear();

// check built docker image content
await checkDockerImageContent({
dockerImageId,
expectedFiles: [
'Dockerfile',
'README.md',
'cache',
'input',
'mock',
'node_modules',
'output',
'package-lock.json',
'package.json',
'src',
],
});
});
});
Expand Down