Skip to content

Commit 42fd8f8

Browse files
authored
Update versioning and user agent handling (#14)
- Bump extension and task version - Added postbuild script to update version from task.json - Included User-Agent header in GitHub API requests - Added tests for User-Agent header format
1 parent 752d83b commit 42fd8f8

File tree

7 files changed

+100
-4
lines changed

7 files changed

+100
-4
lines changed

create-github-app-token/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"build": "tsc",
77
"clean": "rm -rf ./dist ./lib",
88
"prebuild": "npm run clean",
9+
"postbuild": "node scripts/update-version.js",
910
"test": "jest --coverage",
1011
"package": "npm run build && ncc build dist/src/tasks/run.js -o lib/run && ncc build dist/src/tasks/post.js -o lib/post"
1112
},
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require('fs');
4+
const path = require('path');
5+
6+
/**
7+
* Updates the VERSION constant in version.ts with the version from task.json
8+
* This script is run during the build process to ensure the user agent includes the correct version
9+
*/
10+
11+
const taskJsonPath = path.join(__dirname, '..', 'task.json');
12+
const versionPath = path.join(__dirname, '..', 'dist', 'src', 'utils', 'version.js');
13+
14+
try {
15+
// Read task.json to get the version
16+
const taskJsonContent = fs.readFileSync(taskJsonPath, 'utf8');
17+
console.log('Task.json file read successfully');
18+
19+
let taskJson;
20+
try {
21+
taskJson = JSON.parse(taskJsonContent);
22+
} catch (parseError) {
23+
console.error('Error parsing task.json:');
24+
console.error('Parse error:', parseError.message);
25+
console.error('File content length:', taskJsonContent.length);
26+
console.error('Content around error position:');
27+
if (parseError.message.includes('position')) {
28+
const position = parseInt(parseError.message.match(/position (\d+)/)?.[1] || '0');
29+
const start = Math.max(0, position - 50);
30+
const end = Math.min(taskJsonContent.length, position + 50);
31+
console.error(taskJsonContent.substring(start, end));
32+
}
33+
process.exit(1);
34+
}
35+
36+
const version = `${taskJson.version.Major}.${taskJson.version.Minor}.${taskJson.version.Patch}`;
37+
38+
console.log(`Updating version to: ${version}`);
39+
40+
// Check if the version file exists
41+
if (!fs.existsSync(versionPath)) {
42+
console.error(`Version file not found at: ${versionPath}`);
43+
console.error('Make sure to run TypeScript compilation first');
44+
process.exit(1);
45+
}
46+
47+
// Read the compiled version.js file
48+
let versionContent = fs.readFileSync(versionPath, 'utf8');
49+
50+
// Replace the VERSION export
51+
const versionRegex = /exports\.VERSION = ['"]dev['"];/;
52+
const replacement = `exports.VERSION = "${version}";`;
53+
54+
if (!versionRegex.test(versionContent)) {
55+
console.error('Could not find VERSION export in version.js');
56+
console.error('Expected pattern: exports.VERSION = "dev";');
57+
process.exit(1);
58+
}
59+
60+
versionContent = versionContent.replace(versionRegex, replacement);
61+
62+
// Write the updated content back
63+
fs.writeFileSync(versionPath, versionContent, 'utf8');
64+
65+
console.log('Version updated successfully in version.js');
66+
67+
} catch (error) {
68+
console.error('Error updating version:', error.message);
69+
process.exit(1);
70+
}

create-github-app-token/src/core/github-service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as jwt from 'jsonwebtoken';
44
import { ProxyConfig } from './proxy-config';
55
import { validateRepositoryName } from '../utils/validation';
66
import * as constants from '../utils/constants';
7+
import { VERSION, USER_AGENT } from '../utils/version';
78

89
export interface GitHubServiceOptions {
910
proxy?: ProxyConfig;
@@ -21,7 +22,8 @@ export class GitHubService {
2122

2223
const axiosOptions: any = {
2324
headers: {
24-
'Accept': 'application/vnd.github.v3+json'
25+
'Accept': 'application/vnd.github.v3+json',
26+
'User-Agent': `${USER_AGENT}/${VERSION}`
2527
}
2628
};
2729

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Version information - updated during build process
2+
export const VERSION = 'dev'; // This will be replaced during build with actual version from task.json
3+
export const USER_AGENT = 'azure-pipelines-create-github-app-token-task';

create-github-app-token/task.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"version": {
1111
"Major": 1,
1212
"Minor": 0,
13-
"Patch": 5
13+
"Patch": 6
1414
},
1515
"instanceNameFormat": "Create GitHub App Installation Token",
1616
"inputs": [
@@ -20,7 +20,7 @@
2020
"label": "GitHub App Connection",
2121
"defaultValue": "",
2222
"required": false,
23-
"helpMarkDown": "The GitHub App connection to use. If not set, the other inputs will be used instead. This is the preferred way to use this task.",
23+
"helpMarkDown": "The GitHub App connection to use. If not set, the other inputs will be used instead. This is the preferred way to use this task."
2424
},
2525
{
2626
"name": "owner",

create-github-app-token/test/core/github-service.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,26 @@ mockprivatekeydata
686686
});
687687
});
688688

689+
describe('user agent header', () => {
690+
it('should include user agent header with correct format', async () => {
691+
const userAgentPattern = /^azure-pipelines-create-github-app-token-task\/[\w.-]+$/;
692+
693+
const scope = nock(baseUrl)
694+
.get('/orgs/test-org/installation')
695+
.matchHeader('user-agent', userAgentPattern)
696+
.reply(200, {
697+
id: 12345,
698+
repository_selection: 'all',
699+
permissions: { contents: 'read' }
700+
});
701+
702+
const service = new GitHubService(baseUrl);
703+
await service.getInstallationId(mockJwtToken, 'test-app-id', 'test-org', 'org');
704+
705+
expect(scope.isDone()).toBe(true);
706+
});
707+
});
708+
689709
describe('advanced integration scenarios', () => {
690710
it('should handle enterprise GitHub URL normalization', () => {
691711
const enterpriseUrl = 'https://github.enterprise.com/api/v3/';

vss-extension.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"manifestVersion": 1,
33
"id": "create-github-app-token",
44
"name": "GitHub App Token Generator",
5-
"version": "1.0.6",
5+
"version": "1.0.7",
66
"publisher": "INSERT YOUR PUBLISHER HERE",
77
"public": false,
88
"targets": [

0 commit comments

Comments
 (0)