Skip to content

Commit 71e2624

Browse files
committed
Use OS credential manager to store tokens
Also added device token generation
1 parent b0f7cbc commit 71e2624

File tree

7 files changed

+557
-258
lines changed

7 files changed

+557
-258
lines changed

packages/code-infra/package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
"types": "./build/utils/changelog.d.mts",
2222
"default": "./src/utils/changelog.mjs"
2323
},
24-
"./credentials": {
25-
"types": "./build/utils/credentials.d.mts",
26-
"default": "./src/utils/credentials.mjs"
27-
},
2824
"./eslint": {
2925
"types": "./build/eslint/index.d.mts",
3026
"default": "./src/eslint/index.mjs"
3127
},
28+
"./github": {
29+
"types": "./build/utils/github.d.mts",
30+
"default": "./src/utils/github.mjs"
31+
},
3232
"./markdownlint": {
3333
"types": "./build/markdownlint/index.d.mts",
3434
"default": "./src/markdownlint/index.mjs"
@@ -62,15 +62,18 @@
6262
"@mui/internal-babel-plugin-display-name": "workspace:*",
6363
"@mui/internal-babel-plugin-minify-errors": "workspace:*",
6464
"@mui/internal-babel-plugin-resolve-imports": "workspace:*",
65+
"@napi-rs/keyring": "^1.2.0",
6566
"@next/eslint-plugin-next": "^15.5.3",
6667
"@octokit/auth-action": "^6.0.1",
68+
"@octokit/oauth-methods": "^6.0.0",
6769
"@octokit/rest": "^22.0.0",
6870
"@pnpm/find-workspace-dir": "^1000.1.3",
6971
"babel-plugin-optimize-clsx": "^2.6.2",
7072
"babel-plugin-transform-inline-environment-variables": "^0.4.4",
7173
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
7274
"babel-plugin-transform-remove-imports": "^1.8.0",
7375
"chalk": "^5.6.2",
76+
"clipboardy": "^4.0.0",
7477
"eslint-config-prettier": "^10.1.8",
7578
"eslint-import-resolver-typescript": "^4.4.4",
7679
"eslint-module-utils": "^2.12.1",
@@ -86,6 +89,7 @@
8689
"globals": "^16.4.0",
8790
"globby": "^14.1.0",
8891
"minimatch": "^10.0.3",
92+
"open": "^10.2.0",
8993
"postcss-styled-syntax": "^0.7.1",
9094
"regexp.escape": "^2.0.1",
9195
"resolve-pkg-maps": "^1.0.0",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* eslint-disable no-console */
2+
3+
/**
4+
* @typedef {Object} Args
5+
* @property {boolean} authorize
6+
* @property {boolean} clear
7+
*/
8+
9+
export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
10+
command: 'github',
11+
describe: 'Authenticates the user with GitHub and stores the access token securely.',
12+
builder: (yargs) =>
13+
yargs
14+
.option('authorize', {
15+
type: 'boolean',
16+
describe: 'Trigger the authentication flow to get a new token if not found.',
17+
default: false,
18+
})
19+
.option('clear', {
20+
type: 'boolean',
21+
describe: 'Clear stored GitHub authentication tokens.',
22+
default: false,
23+
}),
24+
async handler(args) {
25+
const gh = await import('../utils/github.mjs');
26+
if (args.clear) {
27+
try {
28+
await gh.clearGitHubAuth();
29+
console.log('✅ GitHub authentication cleared');
30+
} catch (/** @type {any} */ error) {
31+
console.error('❌ Failed to clear GitHub authentication:', error.message);
32+
process.exit(1);
33+
}
34+
} else if (args.authorize) {
35+
await gh.endToEndGhAuthGetToken(true);
36+
console.log('✅ GitHub authentication successful');
37+
}
38+
},
39+
});

packages/code-infra/src/cli/index.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import cmdArgosPush from './cmdArgosPush.mjs';
66
import cmdBuild from './cmdBuild.mjs';
77
import cmdCopyFiles from './cmdCopyFiles.mjs';
88
import cmdExtractErrorCodes from './cmdExtractErrorCodes.mjs';
9+
import cmdGithubAuth from './cmdGithubAuth.mjs';
910
import cmdJsonLint from './cmdJsonLint.mjs';
1011
import cmdListWorkspaces from './cmdListWorkspaces.mjs';
1112
import cmdPublish from './cmdPublish.mjs';
@@ -21,6 +22,7 @@ yargs()
2122
.command(cmdBuild)
2223
.command(cmdCopyFiles)
2324
.command(cmdExtractErrorCodes)
25+
.command(cmdGithubAuth)
2426
.command(cmdJsonLint)
2527
.command(cmdListWorkspaces)
2628
.command(cmdPublish)

packages/code-infra/src/utils/changelog.mjs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,41 @@ import { $ } from 'execa';
1616
/**
1717
* @param {Object} opts
1818
* @param {string} opts.cwd
19+
* @param {boolean} [opts.fetchAll=true] Whether to fetch all tags from all remotes before finding the latest tag.
1920
* @returns {Promise<string>}
2021
*/
2122
export async function findLatestTaggedVersion(opts) {
22-
const { stdout } = await $({
23-
cwd: opts.cwd,
24-
// First fetch all tags from all remotes to ensure we have the latest tags. Uses -q flag to suppress output.
25-
// And then find the latest tag matching "v*".
26-
})`git fetch --tags --all -q && git describe --tags --abbrev=0 --match ${'v*'}`; // only include "version-tags"
23+
const $$ = $({ cwd: opts.cwd });
24+
const fetchAll = opts.fetchAll ?? true;
25+
if (fetchAll) {
26+
// Fetch all tags from all remotes to ensure we have the latest tags.
27+
await $$`git fetch --tags --all`;
28+
}
29+
const { stdout } = await $$`git describe --tags --abbrev=0 --match ${'v*'}`; // only include "version-tags"
2730
return stdout.trim();
2831
}
2932

3033
/**
3134
* @typedef {Object} FetchCommitsOptions
32-
* @property {string} token
3335
* @property {string} repo
3436
* @property {string} lastRelease
3537
* @property {string} release
38+
* @property {string} token
3639
* @property {string} [org="mui"]
3740
*/
3841

3942
/**
4043
* Fetches commits between two refs (lastRelease..release) including PR details.
41-
* Throws if the `token` option is not provided.
44+
* Automatically handles GitHub OAuth authentication.
4245
*
4346
* @param {FetchCommitsOptions} param0
4447
* @returns {Promise<FetchedCommitDetails[]>}
4548
*/
4649
export async function fetchCommitsBetweenRefs({ org = 'mui', ...options }) {
4750
if (!options.token) {
48-
throw new Error('Missing "token" option. The token needs `public_repo` permissions.');
51+
throw new Error('GitHub token is required.');
4952
}
53+
5054
const opts = { ...options, org };
5155

5256
return await fetchCommitsRest(opts);
@@ -57,7 +61,7 @@ export async function fetchCommitsBetweenRefs({ org = 'mui', ...options }) {
5761
* It is more reliable than the GraphQL API but requires multiple network calls (1 + n).
5862
* One to list all commits between the two refs and then one for each commit to get the PR details.
5963
*
60-
* @param {FetchCommitsOptions & { org: string }} param0
64+
* @param {FetchCommitsOptions & { org: string, token: string }} param0
6165
*
6266
* @returns {Promise<FetchedCommitDetails[]>}
6367
*/

0 commit comments

Comments
 (0)