(span?: Span)
| 91 | * fails, we fall back to the existing token rather than failing the build. |
| 92 | */ |
| 93 | export async function resolveOidcTokenForBuild(span?: Span): Promise<string> { |
| 94 | const existing = readString(process.env.VERCEL_OIDC_TOKEN); |
| 95 | if (!existing) { |
| 96 | throw new Error( |
| 97 | 'Missing VERCEL_OIDC_TOKEN for the container registry ' + |
| 98 | '(set by the platform or `vercel pull`).' |
| 99 | ); |
| 100 | } |
| 101 | |
| 102 | // A user/CLI auth token is the only credential that can mint a fresh project |
| 103 | // OIDC token. Without it, the existing token is the best we have. |
| 104 | const authToken = readString(process.env.VERCEL_TOKEN); |
| 105 | if (!authToken) { |
| 106 | debug( |
| 107 | 'No VERCEL_TOKEN available to mint; using existing VERCEL_OIDC_TOKEN' |
| 108 | ); |
| 109 | span?.setAttributes({ 'oidc.mint_result': 'reused_existing' }); |
| 110 | debug(`registry token: ${tokenFingerprint(existing)}`); |
| 111 | return existing; |
| 112 | } |
| 113 | |
| 114 | const { projectId, teamId } = resolveProjectContext(existing); |
| 115 | if (!projectId) { |
| 116 | debug('No project id available to mint; using existing VERCEL_OIDC_TOKEN'); |
| 117 | span?.setAttributes({ 'oidc.mint_result': 'reused_existing' }); |
| 118 | return existing; |
| 119 | } |
| 120 | |
| 121 | step('Minting fresh OIDC token for container registry'); |
| 122 | let token: string; |
| 123 | try { |
| 124 | token = await mintProjectOidcToken({ |
| 125 | projectId, |
| 126 | teamId, |
| 127 | authToken, |
| 128 | }); |
| 129 | } catch (err) { |
| 130 | // Minting is an optimization; fall back to the existing token. |
| 131 | debug(`OIDC mint failed, using existing token: ${(err as Error).message}`); |
| 132 | span?.setAttributes({ 'oidc.mint_result': 'failed_reused_existing' }); |
| 133 | return existing; |
| 134 | } |
| 135 | |
| 136 | process.env.VERCEL_OIDC_TOKEN = token; |
| 137 | span?.setAttributes({ |
| 138 | 'oidc.mint_result': 'minted', |
| 139 | 'project.id': projectId, |
| 140 | ...(teamId ? { 'team.id': teamId } : {}), |
| 141 | }); |
| 142 | done('OIDC token minted'); |
| 143 | debug(`registry token: ${tokenFingerprint(token)}`); |
| 144 | return token; |
| 145 | } |
| 146 | |
| 147 | export function formatVcrAuthError( |
| 148 | registry: string, |
no test coverage detected