diff --git a/download/dist/index.js b/download/dist/index.js index 09d8f17..331beef 100644 --- a/download/dist/index.js +++ b/download/dist/index.js @@ -2150,7 +2150,7 @@ function downloadArtifactInternal(artifactId, options) { core.info(`Redirecting to blob download url: ${scrubQueryParameters(signedUrl)}`); try { core.info(`Starting download of artifact to: ${downloadPath}`); - yield streamExtract(signedUrl, downloadPath); + yield streamExtract((0, config_1.normalizeDockerBridgeUrl)(signedUrl), downloadPath); core.info(`Artifact download completed successfully.`); } catch (error) { @@ -2673,7 +2673,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getConcurrency = exports.getGitHubWorkspaceDir = exports.isGhes = exports.getResultsServiceUrl = exports.getRuntimeToken = exports.getUploadChunkSize = void 0; +exports.getConcurrency = exports.getGitHubWorkspaceDir = exports.isGhes = exports.normalizeDockerBridgeUrl = exports.getResultsServiceUrl = exports.getRuntimeToken = exports.getUploadChunkSize = void 0; const os_1 = __importDefault(__nccwpck_require__(22037)); // Used for controlling the highWaterMark value of the zip that is being streamed // The same value is used as the chunk size that is use during upload to blob storage @@ -2694,20 +2694,23 @@ function getResultsServiceUrl() { if (!resultsUrl) { throw new Error('Unable to get the ACTIONS_RESULTS_URL env variable'); } - const serviceUrl = new URL(resultsUrl); - if (serviceUrl.protocol === 'https:' && isDockerBridgeIPv4(serviceUrl.hostname)) { - serviceUrl.protocol = 'http:'; - } - return serviceUrl.origin; + return new URL(normalizeDockerBridgeUrl(resultsUrl)).origin; } exports.getResultsServiceUrl = getResultsServiceUrl; +function normalizeDockerBridgeUrl(rawUrl) { + const serviceUrl = new URL(rawUrl); + if (serviceUrl.protocol === 'https:' && isDockerBridgeIPv4(serviceUrl.hostname)) { + return `http:${rawUrl.slice('https:'.length)}`; + } + return rawUrl; +} +exports.normalizeDockerBridgeUrl = normalizeDockerBridgeUrl; function isDockerBridgeIPv4(hostname) { const octets = hostname.split('.').map(Number); return (octets.length === 4 && octets.every(octet => Number.isInteger(octet) && octet >= 0 && octet <= 255) && octets[0] === 172 && - octets[1] >= 16 && - octets[1] <= 31); + octets[1] === 19); } function isGhes() { return false; diff --git a/tests/internal-results-url.test.js b/tests/internal-results-url.test.js new file mode 100644 index 0000000..0f2d0c2 --- /dev/null +++ b/tests/internal-results-url.test.js @@ -0,0 +1,36 @@ +const assert = require('assert/strict'); +const fs = require('fs'); +const vm = require('vm'); + +const cases = [ + [ + 'https://172.19.153.70:62066/twirp/path?sig=a%2Bb%3D&expires=2026-07-22+21%253A28', + 'http://172.19.153.70:62066/twirp/path?sig=a%2Bb%3D&expires=2026-07-22+21%253A28' + ], + ['http://172.19.153.70:62066/twirp/path?sig=a%2Bb%3D', 'http://172.19.153.70:62066/twirp/path?sig=a%2Bb%3D'], + ['https://172.18.4.8:62066/twirp/path', 'https://172.18.4.8:62066/twirp/path'], + ['https://172.20.4.8:62066/twirp/path', 'https://172.20.4.8:62066/twirp/path'], + ['https://172.31.4.8:62066/twirp/path', 'https://172.31.4.8:62066/twirp/path'], + ['https://git.data-it.tech/api/v1', 'https://git.data-it.tech/api/v1'] +]; + +for (const file of ['upload/dist/index.js', 'download/dist/index.js']) { + const source = fs.readFileSync(file, 'utf8'); + const begin = source.indexOf('function getResultsServiceUrl()'); + const end = source.indexOf('function isGhes()', begin); + assert.ok(begin >= 0 && end >= 0, `${file}: helper segment not found`); + const context = {process: {env: {}}, URL, exports: {}}; + vm.runInNewContext(source.slice(begin, end), context); + for (const [input, expected] of cases) { + assert.equal(context.exports.normalizeDockerBridgeUrl(input), expected, `${file}: ${input}`); + } + context.process.env.ACTIONS_RESULTS_URL = cases[0][0]; + assert.equal(context.exports.getResultsServiceUrl(), 'http://172.19.153.70:62066', `${file}: results service origin`); +} + +const upload = fs.readFileSync('upload/dist/index.js', 'utf8'); +const download = fs.readFileSync('download/dist/index.js', 'utf8'); +assert.ok(upload.includes('new storage_blob_1.BlobClient((0, config_1.normalizeDockerBridgeUrl)(authenticatedUploadURL))')); +assert.ok(download.includes('yield streamExtract((0, config_1.normalizeDockerBridgeUrl)(signedUrl), downloadPath);')); + +console.log('internal results service address checks passed'); diff --git a/upload/dist/index.js b/upload/dist/index.js index 30783f1..3872468 100644 --- a/upload/dist/index.js +++ b/upload/dist/index.js @@ -2998,7 +2998,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getConcurrency = exports.getGitHubWorkspaceDir = exports.isGhes = exports.getResultsServiceUrl = exports.getRuntimeToken = exports.getUploadChunkSize = void 0; +exports.getConcurrency = exports.getGitHubWorkspaceDir = exports.isGhes = exports.normalizeDockerBridgeUrl = exports.getResultsServiceUrl = exports.getRuntimeToken = exports.getUploadChunkSize = void 0; const os_1 = __importDefault(__nccwpck_require__(22037)); // Used for controlling the highWaterMark value of the zip that is being streamed // The same value is used as the chunk size that is use during upload to blob storage @@ -3019,20 +3019,23 @@ function getResultsServiceUrl() { if (!resultsUrl) { throw new Error('Unable to get the ACTIONS_RESULTS_URL env variable'); } - const serviceUrl = new URL(resultsUrl); - if (serviceUrl.protocol === 'https:' && isDockerBridgeIPv4(serviceUrl.hostname)) { - serviceUrl.protocol = 'http:'; - } - return serviceUrl.origin; + return new URL(normalizeDockerBridgeUrl(resultsUrl)).origin; } exports.getResultsServiceUrl = getResultsServiceUrl; +function normalizeDockerBridgeUrl(rawUrl) { + const serviceUrl = new URL(rawUrl); + if (serviceUrl.protocol === 'https:' && isDockerBridgeIPv4(serviceUrl.hostname)) { + return `http:${rawUrl.slice('https:'.length)}`; + } + return rawUrl; +} +exports.normalizeDockerBridgeUrl = normalizeDockerBridgeUrl; function isDockerBridgeIPv4(hostname) { const octets = hostname.split('.').map(Number); return (octets.length === 4 && octets.every(octet => Number.isInteger(octet) && octet >= 0 && octet <= 255) && octets[0] === 172 && - octets[1] >= 16 && - octets[1] <= 31); + octets[1] === 19); } function isGhes() { return false; @@ -3307,7 +3310,7 @@ function uploadZipToBlobStorage(authenticatedUploadURL, zipUploadStream) { let uploadByteCount = 0; const maxConcurrency = (0, config_1.getConcurrency)(); const bufferSize = (0, config_1.getUploadChunkSize)(); - const blobClient = new storage_blob_1.BlobClient(authenticatedUploadURL); + const blobClient = new storage_blob_1.BlobClient((0, config_1.normalizeDockerBridgeUrl)(authenticatedUploadURL)); const blockBlobClient = blobClient.getBlockBlobClient(); core.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`); const uploadCallback = (progress) => {