Skip to content

chore(ci): migrate ai-platform/snippets via ESM #4102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions .github/config/nodejs-dev.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"recaptcha_enterprise/demosite/app", // no tests exist

// These tests are already passing in prod, so skip them in dev.
"ai-platform/snippets",
"appengine/building-an-app/build",
"appengine/building-an-app/update",
"appengine/datastore",
Expand Down
1 change: 0 additions & 1 deletion .github/config/nodejs.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
"recaptcha_enterprise/demosite/app", // no tests exist

// TODO: fix these
"ai-platform/snippets", // PERMISSION_DENIED: Permission denied: Consumer 'projects/undefined' has been suspended.
"automl", // (untested) FAILED_PRECONDITION: Google Cloud AutoML Natural Language was retired on March 15, 2024. Please migrate to Vertex AI instead
"cloud-sql/sqlserver/tedious", // (untested) TypeError: The "config.server" property is required and must be of type string.
"compute", // GoogleError: The resource 'projects/long-door-651/zones/us-central1-a/disks/disk-from-pool-name' was not found
Expand Down
6 changes: 6 additions & 0 deletions ai-platform/snippets/ci-setup.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"timeout-minutes": 20,
"secrets": {
"CAIP_PROJECT_ID": "nodejs-docs-samples-tests/nodejs-docs-samples-ai-platform-caip-project-id"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

'use strict';

const path = require('path');
const {assert} = require('chai');
const {after, describe, it} = require('mocha');
const uuid = require('uuid').v4;
const cp = require('child_process');
import path from 'node:path';
import {assert} from 'chai';
import {after, describe, it} from 'mocha';
import {v4 as uuid} from 'uuid';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cwd = path.join(__dirname, '..');
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The __dirname variable is not available by default in ES modules, leading to a ReferenceError at runtime. Refactor to determine the current directory path in an ESM context.

This issue applies to many other test files using __dirname:

  • ai-platform/snippets/expensive-test/create-data-labeling-job-video.test.js
  • ai-platform/snippets/expensive-test/create-data-labeling-job.test.js
  • ai-platform/snippets/test/create-batch-prediction-job-video-classification.test.js
  • ...and others.

Update these files to use the ESM-compatible way of getting the directory name?

Suggested change
const cwd = path.join(__dirname, '..');
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const cwd = path.join(__dirname, '..');


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@

'use strict';

const path = require('path');
const {assert} = require('chai');
const {after, describe, it} = require('mocha');

const uuid = require('uuid').v4;
const cp = require('child_process');
import path from 'node:path';
import {assert} from 'chai';
import {after, describe, it} from 'mocha';
import {v4 as uuid} from 'uuid';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cwd = path.join(__dirname, '..');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@

'use strict';

const path = require('path');
const {assert} = require('chai');
const {after, describe, it} = require('mocha');

const uuid = require('uuid').v4;
const cp = require('child_process');
import path from 'node:path';
import {assert} from 'chai';
import {after, describe, it} from 'mocha';
import {v4 as uuid} from 'uuid';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cwd = path.join(__dirname, '..');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@

'use strict';

const path = require('path');
const {assert} = require('chai');
const {describe, it} = require('mocha');

const cp = require('child_process');
import path from 'node:path';
import {assert} from 'chai';
import {describe, it} from 'mocha';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cwd = path.join(__dirname, '..');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@

'use strict';

const path = require('path');
const {assert} = require('chai');
const {describe, it} = require('mocha');

const cp = require('child_process');
import path from 'node:path';
import {assert} from 'chai';
import {describe, it} from 'mocha';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cwd = path.join(__dirname, '..');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@

'use strict';

const path = require('path');
const {assert} = require('chai');
const {describe, it} = require('mocha');

const cp = require('child_process');
import path from 'node:path';
import {assert} from 'chai';
import {describe, it} from 'mocha';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cwd = path.join(__dirname, '..');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@

'use strict';

const path = require('path');
const {assert} = require('chai');
const {describe, it} = require('mocha');

const cp = require('child_process');
import path from 'node:path';
import {assert} from 'chai';
import {describe, it} from 'mocha';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cwd = path.join(__dirname, '..');

Expand Down
2 changes: 1 addition & 1 deletion ai-platform/snippets/gemma2PredictGpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ async function gemma2PredictGpu(predictionServiceClient) {
return text;
}

module.exports = gemma2PredictGpu;
export default gemma2PredictGpu;

// TODO(developer): Uncomment below lines before running the sample.
// gemma2PredictGpu(...process.argv.slice(2)).catch(err => {
Expand Down
2 changes: 1 addition & 1 deletion ai-platform/snippets/gemma2PredictTpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ async function gemma2PredictTpu(predictionServiceClient) {
return text;
}

module.exports = gemma2PredictTpu;
export default gemma2PredictTpu;

// TODO(developer): Uncomment below lines before running the sample.
// gemma2PredictTpu(...process.argv.slice(2)).catch(err => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ async function main() {
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function editImageInpaintingInsertMask() {
const fs = require('fs');
const util = require('util');
const fs = require('node:fs');
const util = require('node:util');
Comment on lines +47 to +48
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

These require calls for fs and util are inside a function within an ES module. Use top-level import statements for better ESM compatibility. This also applies to the require('@google-cloud/aiplatform') on line 30.

This pattern is present in several other imagen-*.js, predict-custom-trained-model.js, predict-image-classification.js, and predict-image-object-detection.js files. Refactor to use top-level imports?

import fs from 'node:fs';
import util from 'node:util';

// Configure the parent resource
const endpoint = `projects/${projectId}/locations/${location}/publishers/google/models/imagegeneration@006`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ async function main() {
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function editImageInpaintingRemoveMask() {
const fs = require('fs');
const util = require('util');
const fs = require('node:fs');
const util = require('node:util');
// Configure the parent resource
const endpoint = `projects/${projectId}/locations/${location}/publishers/google/models/imagegeneration@006`;

Expand Down
4 changes: 2 additions & 2 deletions ai-platform/snippets/imagen-edit-image-mask-free.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ async function main() {
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function editImageMaskFree() {
const fs = require('fs');
const util = require('util');
const fs = require('node:fs');
const util = require('node:util');
// Configure the parent resource
const endpoint = `projects/${projectId}/locations/${location}/publishers/google/models/imagegeneration@002`;

Expand Down
4 changes: 2 additions & 2 deletions ai-platform/snippets/imagen-edit-image-outpainting-mask.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ async function main() {
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function editImageOutpaintingMask() {
const fs = require('fs');
const util = require('util');
const fs = require('node:fs');
const util = require('node:util');
// Configure the parent resource
const endpoint = `projects/${projectId}/locations/${location}/publishers/google/models/imagegeneration@006`;

Expand Down
4 changes: 2 additions & 2 deletions ai-platform/snippets/imagen-generate-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ async function main() {
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function generateImage() {
const fs = require('fs');
const util = require('util');
const fs = require('node:fs');
const util = require('node:util');
// Configure the parent resource
const endpoint = `projects/${projectId}/locations/${location}/publishers/google/models/imagen-3.0-generate-001`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ async function main() {
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function getShortFormImageCaptions() {
const fs = require('fs');
const fs = require('node:fs');
// Configure the parent resource
const endpoint = `projects/${projectId}/locations/${location}/publishers/google/models/imagetext@001`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async function main() {
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function getShortFormImageResponses() {
const fs = require('fs');
const fs = require('node:fs');
// Configure the parent resource
const endpoint = `projects/${projectId}/locations/${location}/publishers/google/models/imagetext@001`;

Expand Down
16 changes: 8 additions & 8 deletions ai-platform/snippets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@
"private": true,
"license": "Apache-2.0",
"author": "Google LLC",
"type": "module",
"engines": {
"node": ">=16.0.0"
},
"files": [
"*.js"
],
"scripts": {
"test": "c8 mocha -p -j 2 --timeout 2400000 test/*.js"
"test": "c8 mocha -p -j 2 --timeout 2400000 test/*.js --reporter list"
},
"dependencies": {
"@google-cloud/aiplatform": "^3.0.0",
"@google-cloud/bigquery": "^7.0.0",
"@google-cloud/aiplatform": "^4.0.0",
"@google-cloud/bigquery": "^8.0.0",
"@google-cloud/storage": "^7.0.0"
},
"devDependencies": {
"c8": "^10.0.0",
"chai": "^4.5.0",
"mocha": "^10.0.0",
"uuid": "^10.0.0",
"sinon": "^18.0.0"
"chai": "^5.0.0",
"mocha": "^11.0.0",
"uuid": "^11.0.0",
"sinon": "^20.0.0"
}
}

4 changes: 2 additions & 2 deletions ai-platform/snippets/predict-custom-trained-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ async function main(filename, endpointId, project, location = 'us-central1') {
// const endpointId = "YOUR_ENDPOINT_ID";
// const project = 'YOUR_PROJECT_ID';
// const location = 'YOUR_PROJECT_LOCATION';
const util = require('util');
const {readFile} = require('fs');
const util = require('node:util');
const {readFile} = require('node:fs');
const readFileAsync = util.promisify(readFile);

// Imports the Google Cloud Prediction Service Client library
Expand Down
2 changes: 1 addition & 1 deletion ai-platform/snippets/predict-image-classification.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function main(filename, endpointId, project, location = 'us-central1') {
});
const parameters = parametersObj.toValue();

const fs = require('fs');
const fs = require('node:fs');
const image = fs.readFileSync(filename, 'base64');
const instanceObj = new instance.ImageClassificationPredictionInstance({
content: image,
Expand Down
4 changes: 2 additions & 2 deletions ai-platform/snippets/predict-image-from-image-and-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async function main(
// Configure the parent resource
const endpoint = `projects/${project}/locations/${location}/publishers/${publisher}/models/${model}`;

const fs = require('fs');
const fs = require('node:fs');
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to other snippet files, this require('node:fs') is inside a function in an ES module. Move this to a top-level import fs from 'node:fs'; statement.

import fs from 'node:fs';

const imageFile = fs.readFileSync(baseImagePath);

// Convert the image data to a Buffer and base64 encode it.
Expand Down Expand Up @@ -95,4 +95,4 @@ async function main(
// [END generativeaionvertexai_sdk_text_image_embedding]
}

exports.predictImageFromImageAndText = main;
export {main as predictImageFromImageAndText};
2 changes: 1 addition & 1 deletion ai-platform/snippets/predict-image-object-detection.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function main(filename, endpointId, project, location = 'us-central1') {
});
const parameters = parametersObj.toValue();

const fs = require('fs');
const fs = require('node:fs');
const image = fs.readFileSync(filename, 'base64');
const instanceObj = new instance.ImageObjectDetectionPredictionInstance({
content: image,
Expand Down
10 changes: 5 additions & 5 deletions ai-platform/snippets/test/batch-prediction-gemini.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

'use strict';

const {assert} = require('chai');
const {after, describe, it} = require('mocha');
const cp = require('child_process');
const {JobServiceClient} = require('@google-cloud/aiplatform');
import { assert } from 'chai';
import { after, describe, it } from 'mocha';
import { execSync as _execSync } from 'node:child_process';
import { JobServiceClient } from '@google-cloud/aiplatform';

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const execSync = cmd => _execSync(cmd, {encoding: 'utf-8'});

describe('Batch predict with Gemini', async () => {
const projectId = process.env.CAIP_PROJECT_ID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@

'use strict';

const {assert} = require('chai');
const {after, describe, it} = require('mocha');
const uuid = require('uuid').v4;
const cp = require('child_process');
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
import { assert } from 'chai';
import { after, describe, it } from 'mocha';
import { v4 as uuid } from 'uuid';
import { execSync as _execSync } from 'node:child_process';
const execSync = cmd => _execSync(cmd, {encoding: 'utf-8'});

const aiplatform = require('@google-cloud/aiplatform');
import { v1 } from '@google-cloud/aiplatform';
const clientOptions = {
apiEndpoint: 'us-central1-aiplatform.googleapis.com',
};

const jobServiceClient = new aiplatform.v1.JobServiceClient(clientOptions);
const jobServiceClient = new v1.JobServiceClient(clientOptions);

const batchPredictionDisplayName = `temp_create_batch_prediction_text_classification_test${uuid()}`;
const modelId = '7827432074230366208';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

'use strict';

const {assert} = require('chai');
const {after, describe, it} = require('mocha');
const uuid = require('uuid').v4;
const cp = require('child_process');
import {assert} from 'chai';
import {after, describe, it} from 'mocha';
import {v4 as uuid} from 'uuid';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});

const aiplatform = require('@google-cloud/aiplatform');
import aiplatform from '@google-cloud/aiplatform';
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The import import aiplatform from '@google-cloud/aiplatform'; is a default import. Later, aiplatform.v1.JobServiceClient is used.

Other files (e.g., create-batch-prediction-job-text-classification.test.js) use import { v1 } from '@google-cloud/aiplatform'; followed by new v1.JobServiceClient(). Standardize the import style for @google-cloud/aiplatform across test files for consistency. Check the recommended import style for @google-cloud/aiplatform v4 and apply it consistently?

const clientOptions = {
apiEndpoint: 'us-central1-aiplatform.googleapis.com',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

'use strict';

const {assert} = require('chai');
const {after, describe, it} = require('mocha');
const uuid = require('uuid').v4;
const cp = require('child_process');
import {assert} from 'chai';
import {after, describe, it} from 'mocha';
import {v4 as uuid} from 'uuid';
import cp from 'node:child_process';
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});

const aiplatform = require('@google-cloud/aiplatform');
import aiplatform from '@google-cloud/aiplatform';
const clientOptions = {
apiEndpoint: 'us-central1-aiplatform.googleapis.com',
};
Expand Down
Loading
Loading