diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..50a8fbc --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + cooldown: + default-days: 7 + groups: + minor-and-patch: + update-types: + - minor + - patch diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c0aaa70..5098dc5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,9 +19,9 @@ jobs: steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: token: ${{ secrets.GITHUB_TOKEN }} node-version: 20 @@ -42,7 +42,7 @@ jobs: - run: npm run build - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: js path: | @@ -81,14 +81,14 @@ jobs: # cpu: darwin_x86_64 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 if: ${{ !env.ACT }} with: name: js - - uses: bazel-contrib/setup-bazel@0.8.5 + - uses: bazel-contrib/setup-bazel@e403ad507104847c3539436f64a9e9eecc73eeec # 0.8.5 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -102,7 +102,7 @@ jobs: # need to copy to output directory as `bazel-bin` is a symlink and cannot be read by the actions/upload-artifact action - run: cp bazel-bin/protobuf-javascript-* out/ - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: release-${{ matrix.os }}-${{ matrix.cpu }} path: out @@ -116,12 +116,12 @@ jobs: contents: write steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: release-${{ matrix.os }}-${{ matrix.cpu }} - name: Release - uses: svenstaro/upload-release-action@v2 + uses: svenstaro/upload-release-action@29e53e917877a24fad85510ded594ab3c9ca12de # v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: protobuf-javascript-* diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dccc072..b26b739 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -49,11 +49,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@42947a340483f03ba47bb1a039b2c519aab3df85 # v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -81,4 +81,4 @@ jobs: - run: npm test - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@42947a340483f03ba47bb1a039b2c519aab3df85 # v3 diff --git a/binary/utils.js b/binary/utils.js index 3c8bac6..d527046 100644 --- a/binary/utils.js +++ b/binary/utils.js @@ -36,10 +36,9 @@ * @author aappleby@google.com (Austin Appleby) */ -import * as crypt from '../../closure-library/closure/goog/crypt/crypt.js'; - -import * as base64 from '../../closure-library/closure/goog/crypt/base64.js'; -import * as googString from '../../closure-library/closure/goog/string/string.js'; +import crypt from 'goog:goog.crypt'; +import base64 from 'goog:goog.crypt.base64'; +import googString from 'goog:goog.string'; import * as asserts from '../asserts.js'; import * as BinaryConstants from './constants.js'; diff --git a/binary/writer.js b/binary/writer.js index 416bf24..36a65a0 100644 --- a/binary/writer.js +++ b/binary/writer.js @@ -56,7 +56,7 @@ * @author aappleby@google.com (Austin Appleby) */ -import * as base64 from '../../closure-library/closure/goog/crypt/base64.js'; +import base64 from 'goog:goog.crypt.base64'; import * as asserts from '../asserts.js'; import * as BinaryConstants from './constants.js'; diff --git a/commonjs/export_testdeps.js b/commonjs/export_testdeps.js index be0c472..b6b9b70 100644 --- a/commonjs/export_testdeps.js +++ b/commonjs/export_testdeps.js @@ -7,12 +7,12 @@ * export_asserts.js. */ -import { byteArrayToString, byteArrayToHex } from '../../closure-library/closure/goog/crypt/crypt.js'; -import * as base64 from '../../closure-library/closure/goog/crypt/base64.js'; -import { PropertyReplacer } from '../../closure-library/closure/goog/testing/propertyreplacer.js'; -import * as userAgent from '../../closure-library/closure/goog/useragent/useragent.js'; -import * as googArray from '../../closure-library/closure/goog/array/array.js'; -import googObject from '../../closure-library/closure/goog/object/object.js'; +import { byteArrayToString, byteArrayToHex } from 'goog:goog.crypt'; +import base64 from 'goog:goog.crypt.base64'; +import PropertyReplacer from 'goog:goog.testing.PropertyReplacer'; +import userAgent from 'goog:goog.userAgent'; +import googArray from 'goog:goog.array'; +import googObject from 'goog:goog.object'; import * as debug from '../debug.js' import { BinaryReader } from '../binary/reader.js'; diff --git a/debug.js b/debug.js index 74ff11e..250da42 100644 --- a/debug.js +++ b/debug.js @@ -32,10 +32,8 @@ * @fileoverview Utilities to debug JSPB based proto objects. */ -import '../closure-library/closure/goog/array/array.js'; - -import * as googArray from '../closure-library/closure/goog/array/array.js'; -import googObject from '../closure-library/closure/goog/object/object.js'; +import googArray from 'goog:goog.array'; +import googObject from 'goog:goog.object'; import * as asserts from './asserts.js'; import { Map } from './map.js'; import { Message } from './message.js'; diff --git a/gulpfile.js b/gulpfile.js index 764651b..f342d05 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,6 +1,8 @@ const {series} = require('gulp'); const execFile = require('child_process').execFile; const glob = require('glob'); +const fs = require('fs'); +const path = require('path'); function exec(command, cb) { execFile('sh', ['-c', command], cb); @@ -9,6 +11,7 @@ function exec(command, cb) { const plugin = '--plugin=protoc-gen-js=bazel-bin/generator/protoc-gen-js'; const protoc = [(process.env.PROTOC || 'bazel-bin/external/com_google_protobuf/protoc'), plugin].join(' '); const protocInc = process.env.PROTOC_INC || 'bazel-protobuf-javascript/external/com_google_protobuf/src'; +const closureLib = '../closure-library'; // See https://github.com/google/closure-compiler/wiki/Flags-and-Options let compilationLevel = 'SIMPLE'; @@ -130,8 +133,26 @@ function genproto_group3_commonjs_strict(cb) { } +function linkClosureLibrary() { + // lstat sees the link itself and exists() resolves it, so they disagree + // exactly when the link is dangling -- replace it rather than leave it broken. + // A real sibling checkout (the pre-existing convention) is left alone. + try { + fs.lstatSync(closureLib); + if (fs.existsSync(closureLib)) return; + fs.unlinkSync(closureLib); + } catch (e) { + if (e.code !== 'ENOENT') throw e; + } + // Symlink targets resolve relative to the link's location, not the process's + // cwd, so the target has to be absolute. + fs.symlinkSync(path.resolve('node_modules/google-closure-library'), closureLib, 'dir'); +} + function getClosureCompilerCommand(exportsFile, outputFile) { - const closureLib = '../closure-library'; + // The --js= globs below read from '../closure-library', not the npm install + // path (node_modules/google-closure-library) -- symlink it so they resolve. + linkClosureLibrary(); return [ 'node_modules/.bin/google-closure-compiler', `--js=${closureLib}/closure/goog/**.js`, @@ -211,14 +232,25 @@ function test_commonjs(cb) { } function remove_gen_files(cb) { + // Only the symlink linkClosureLibrary() made is ours to delete; ../closure-library + // may be a real sibling checkout, which rm -rf would take out recursively. + try { + if (fs.lstatSync(closureLib).isSymbolicLink()) fs.unlinkSync(closureLib); + } catch (e) { + if (e.code !== 'ENOENT') throw e; + } exec('rm -rf commonjs_out google-protobuf.js deps.js', make_exec_logging_callback(cb)); } exports.build_protoc_plugin = function (cb) { - exec('bazel build generator:protoc-gen-js', - make_exec_logging_callback(cb)); - exec('bazel build @com_google_protobuf//:protoc', + // Both bazel builds ran as separate async exec() calls sharing one cb, + // so cb() fired after whichever finished first -- gulp would advance + // to the next task (which invokes bazel-bin/generator/protoc-gen-js) + // before that build was necessarily done, intermittently failing with + // "program not found or is not executable". Joined into one shell + // command so cb() only fires once, after both have actually finished. + exec('bazel build generator:protoc-gen-js && bazel build @com_google_protobuf//:protoc', make_exec_logging_callback(cb)); } diff --git a/message.js b/message.js index 9f1ac51..c2427a4 100644 --- a/message.js +++ b/message.js @@ -35,9 +35,9 @@ * @author mwr@google.com (Mark Rawling) */ -import * as googArray from '../closure-library/closure/goog/array/array.js'; +import googArray from 'goog:goog.array'; -import * as base64 from '../closure-library/closure/goog/crypt/base64.js'; +import base64 from 'goog:goog.crypt.base64'; import * as asserts from './asserts.js'; import { BinaryReader } from './binary/reader.js'; import { BinaryWriter } from './binary/writer.js';