refactor: replace requireVariable and requireInput with task-lib equivalents and improve error handling
This commit is contained in:
@@ -1,18 +1,26 @@
|
||||
import * as tl from 'azure-pipelines-task-lib/task';
|
||||
import {
|
||||
buildOidcUrl,
|
||||
exchangeOidcForScopedToken,
|
||||
getServiceConnectionMetadata,
|
||||
requestOidcToken
|
||||
} from './oidc';
|
||||
import { requireVariable } from './devops-helpers';
|
||||
|
||||
export const STORAGE_SCOPE = 'https://storage.azure.com/.default';
|
||||
|
||||
export async function requestStorageAccessToken(
|
||||
endpointId: string
|
||||
): Promise<string> {
|
||||
const oidcBaseUrl = requireVariable('System.OidcRequestUri');
|
||||
const systemAccessToken = requireVariable('System.AccessToken');
|
||||
const oidcBaseUrl = tl.getVariable('System.OidcRequestUri');
|
||||
const systemAccessToken = tl.getVariable('System.AccessToken');
|
||||
|
||||
if (oidcBaseUrl === undefined) {
|
||||
throw new Error('Missing required pipeline variable: System.OidcRequestUri.');
|
||||
}
|
||||
|
||||
if (systemAccessToken === undefined) {
|
||||
throw new Error('Missing required pipeline variable: System.AccessToken.');
|
||||
}
|
||||
|
||||
const metadata = getServiceConnectionMetadata(endpointId);
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
type TaskLibBridge = {
|
||||
getInput: (name: string, required?: boolean) => string | undefined;
|
||||
getVariable: (name: string) => string | undefined;
|
||||
};
|
||||
|
||||
function getTaskLibBridge(): TaskLibBridge {
|
||||
return require('azure-pipelines-task-lib/task') as TaskLibBridge;
|
||||
}
|
||||
|
||||
export function requireInput(name: string): string {
|
||||
const taskLib = getTaskLibBridge();
|
||||
const value = taskLib.getInput(name, true);
|
||||
if (!value) {
|
||||
throw new Error(`Task input ${name} is required.`);
|
||||
}
|
||||
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
export function requireVariable(name: string): string {
|
||||
const taskLib = getTaskLibBridge();
|
||||
const value = taskLib.getVariable(name);
|
||||
if (!value) {
|
||||
throw new Error(`Missing required pipeline variable: ${name}.`);
|
||||
}
|
||||
|
||||
return value.trim();
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './devops-helpers';
|
||||
export * from './oidc';
|
||||
export * from './blob';
|
||||
@@ -1,3 +1,5 @@
|
||||
import * as tl from 'azure-pipelines-task-lib/task';
|
||||
|
||||
export type ServiceConnectionMetadata = {
|
||||
tenantId: string;
|
||||
clientId: string;
|
||||
@@ -11,40 +13,25 @@ export type TokenResponse = {
|
||||
|
||||
export const CLIENT_ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';
|
||||
|
||||
type TaskLibEndpointBridge = {
|
||||
getEndpointAuthorizationParameter: (
|
||||
endpointId: string,
|
||||
key: string,
|
||||
optional: boolean
|
||||
) => string | undefined;
|
||||
getEndpointDataParameter: (endpointId: string, key: string, optional: boolean) => string | undefined;
|
||||
};
|
||||
|
||||
type OidcResponse = {
|
||||
oidcToken?: string;
|
||||
};
|
||||
|
||||
function getTaskLibEndpointBridge(): TaskLibEndpointBridge {
|
||||
return require('azure-pipelines-task-lib/task') as TaskLibEndpointBridge;
|
||||
}
|
||||
|
||||
export function getServiceConnectionMetadata(endpointId: string): ServiceConnectionMetadata {
|
||||
const taskLib = getTaskLibEndpointBridge();
|
||||
|
||||
const tenantId =
|
||||
taskLib.getEndpointAuthorizationParameter(endpointId, 'tenantid', true) ||
|
||||
taskLib.getEndpointDataParameter(endpointId, 'tenantid', true);
|
||||
tl.getEndpointAuthorizationParameter(endpointId, 'tenantid', true) ||
|
||||
tl.getEndpointDataParameter(endpointId, 'tenantid', true);
|
||||
|
||||
const clientId =
|
||||
taskLib.getEndpointAuthorizationParameter(endpointId, 'serviceprincipalid', true) ||
|
||||
taskLib.getEndpointAuthorizationParameter(endpointId, 'clientid', true) ||
|
||||
taskLib.getEndpointDataParameter(endpointId, 'serviceprincipalid', true);
|
||||
tl.getEndpointAuthorizationParameter(endpointId, 'serviceprincipalid', true) ||
|
||||
tl.getEndpointAuthorizationParameter(endpointId, 'clientid', true) ||
|
||||
tl.getEndpointDataParameter(endpointId, 'serviceprincipalid', true);
|
||||
|
||||
if (!tenantId) {
|
||||
if (tenantId === undefined) {
|
||||
throw new Error('Could not resolve tenant ID from the selected AzureRM service connection.');
|
||||
}
|
||||
|
||||
if (!clientId) {
|
||||
if (clientId === undefined) {
|
||||
throw new Error('Could not resolve client ID from the selected AzureRM service connection.');
|
||||
}
|
||||
|
||||
|
||||
@@ -4,21 +4,27 @@ import {
|
||||
buildOidcUrl,
|
||||
exchangeOidcForScopedToken,
|
||||
getServiceConnectionMetadata,
|
||||
requestOidcToken,
|
||||
requireInput,
|
||||
requireVariable
|
||||
requestOidcToken
|
||||
} from '@skoszewski/ado-sk-toolkit-shared';
|
||||
|
||||
const AZDO_APP_SCOPE = '499b84ac-1321-427f-aa17-267ca6975798/.default';
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const endpointId = requireInput('serviceConnectionARM');
|
||||
const endpointId = tl.getInputRequired('serviceConnectionARM');
|
||||
const setGitAccessToken = tl.getBoolInput('setGitAccessToken', false);
|
||||
const printTokenHashes = tl.getBoolInput('printTokenHashes', false);
|
||||
|
||||
const oidcBaseUrl = requireVariable('System.OidcRequestUri');
|
||||
const accessToken = requireVariable('System.AccessToken');
|
||||
const oidcBaseUrl = tl.getVariable('System.OidcRequestUri');
|
||||
const accessToken = tl.getVariable('System.AccessToken');
|
||||
|
||||
if (oidcBaseUrl === undefined) {
|
||||
throw new Error('Missing required pipeline variable: System.OidcRequestUri.');
|
||||
}
|
||||
|
||||
if (accessToken === undefined) {
|
||||
throw new Error('Missing required pipeline variable: System.AccessToken.');
|
||||
}
|
||||
|
||||
console.log('Requesting OIDC token for ARM authentication...');
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import * as tl from 'azure-pipelines-task-lib/task';
|
||||
import {
|
||||
buildBlobUrl,
|
||||
requestStorageAccessToken,
|
||||
requireInput
|
||||
requestStorageAccessToken
|
||||
} from '@skoszewski/ado-sk-toolkit-shared';
|
||||
|
||||
async function copyBlob(
|
||||
@@ -38,12 +37,12 @@ async function copyBlob(
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const endpointId = requireInput('serviceConnectionARM');
|
||||
const srcStorageAccountName = requireInput('srcStorageAccountName');
|
||||
const dstStorageAccountName = requireInput('dstStorageAccountName');
|
||||
const srcContainerName = requireInput('srcContainerName');
|
||||
const dstContainerNameInput = tl.getInput('dstContainerName', false)?.trim() || '';
|
||||
const blobName = requireInput('blobName');
|
||||
const endpointId = tl.getInputRequired('serviceConnectionARM');
|
||||
const srcStorageAccountName = tl.getInputRequired('srcStorageAccountName');
|
||||
const dstStorageAccountName = tl.getInputRequired('dstStorageAccountName');
|
||||
const srcContainerName = tl.getInputRequired('srcContainerName');
|
||||
const dstContainerNameInput = tl.getInput('dstContainerName', false) || '';
|
||||
const blobName = tl.getInputRequired('blobName');
|
||||
|
||||
console.log('Requesting storage access token from Microsoft Entra ID...');
|
||||
const accessToken = await requestStorageAccessToken(endpointId);
|
||||
|
||||
@@ -3,8 +3,7 @@ import * as path from 'node:path';
|
||||
import * as tl from 'azure-pipelines-task-lib/task';
|
||||
import {
|
||||
buildBlobUrl,
|
||||
requestStorageAccessToken,
|
||||
requireInput
|
||||
requestStorageAccessToken
|
||||
} from '@skoszewski/ado-sk-toolkit-shared';
|
||||
|
||||
async function downloadBlob(blobUrl: string, bearerToken: string): Promise<Buffer> {
|
||||
@@ -28,11 +27,11 @@ async function downloadBlob(blobUrl: string, bearerToken: string): Promise<Buffe
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const endpointId = requireInput('serviceConnectionARM');
|
||||
const storageAccountName = requireInput('storageAccountName');
|
||||
const containerName = requireInput('containerName');
|
||||
const blobName = requireInput('blobName');
|
||||
const destinationPath = requireInput('destinationPath');
|
||||
const endpointId = tl.getInputRequired('serviceConnectionARM');
|
||||
const storageAccountName = tl.getInputRequired('storageAccountName');
|
||||
const containerName = tl.getInputRequired('containerName');
|
||||
const blobName = tl.getInputRequired('blobName');
|
||||
const destinationPath = tl.getInputRequired('destinationPath');
|
||||
|
||||
console.log('Requesting storage access token from Microsoft Entra ID...');
|
||||
const accessToken = await requestStorageAccessToken(endpointId);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as tl from 'azure-pipelines-task-lib/task';
|
||||
import {
|
||||
requestStorageAccessToken,
|
||||
requireInput
|
||||
requestStorageAccessToken
|
||||
} from '@skoszewski/ado-sk-toolkit-shared';
|
||||
|
||||
function decodeXmlValue(value: string): string {
|
||||
@@ -60,11 +59,11 @@ async function listBlobs(listUrl: string, bearerToken: string): Promise<string[]
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const endpointId = requireInput('serviceConnectionARM');
|
||||
const storageAccountName = requireInput('storageAccountName');
|
||||
const containerName = requireInput('containerName');
|
||||
const prefix = tl.getInput('prefix', false)?.trim() || '';
|
||||
const maxResultsRaw = tl.getInput('maxResults', false)?.trim() || '1000';
|
||||
const endpointId = tl.getInputRequired('serviceConnectionARM');
|
||||
const storageAccountName = tl.getInputRequired('storageAccountName');
|
||||
const containerName = tl.getInputRequired('containerName');
|
||||
const prefix = tl.getInput('prefix', false) || '';
|
||||
const maxResultsRaw = tl.getInput('maxResults', false) || '1000';
|
||||
const maxResults = Number.parseInt(maxResultsRaw, 10);
|
||||
|
||||
if (!Number.isInteger(maxResults) || maxResults <= 0) {
|
||||
|
||||
@@ -2,8 +2,7 @@ import * as fs from 'node:fs/promises';
|
||||
import * as tl from 'azure-pipelines-task-lib/task';
|
||||
import {
|
||||
buildBlobUrl,
|
||||
requestStorageAccessToken,
|
||||
requireInput
|
||||
requestStorageAccessToken
|
||||
} from '@skoszewski/ado-sk-toolkit-shared';
|
||||
|
||||
async function uploadBlob(
|
||||
@@ -35,12 +34,12 @@ async function uploadBlob(
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const endpointId = requireInput('serviceConnectionARM');
|
||||
const storageAccountName = requireInput('storageAccountName');
|
||||
const containerName = requireInput('containerName');
|
||||
const blobName = requireInput('blobName');
|
||||
const sourcePath = requireInput('sourcePath');
|
||||
const contentType = tl.getInput('contentType', false)?.trim() || 'application/octet-stream';
|
||||
const endpointId = tl.getInputRequired('serviceConnectionARM');
|
||||
const storageAccountName = tl.getInputRequired('storageAccountName');
|
||||
const containerName = tl.getInputRequired('containerName');
|
||||
const blobName = tl.getInputRequired('blobName');
|
||||
const sourcePath = tl.getInputRequired('sourcePath');
|
||||
const contentType = tl.getInput('contentType', false) || 'application/octet-stream';
|
||||
|
||||
console.log('Requesting storage access token from Microsoft Entra ID...');
|
||||
const accessToken = await requestStorageAccessToken(endpointId);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifestVersion": 1,
|
||||
"id": "sk-azure-devops-toolkit",
|
||||
"name": "SK Azure DevOps Toolkit",
|
||||
"version": "1.0.5",
|
||||
"version": "1.1.0",
|
||||
"publisher": "skoszewski-lab",
|
||||
"targets": [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user