From 07fea2963e0c1c410412894840afa5d1ae91744e Mon Sep 17 00:00:00 2001 From: peli Date: Fri, 19 Jun 2020 09:42:09 -0700 Subject: [PATCH 01/10] getting a start on master/main conversion --- cli/cli.ts | 63 +++++++++--------------------------------------- pxtlib/github.ts | 10 ++++++++ 2 files changed, 21 insertions(+), 52 deletions(-) diff --git a/cli/cli.ts b/cli/cli.ts index b29ac02b5931..13530f1a9045 100644 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -400,18 +400,18 @@ function ciAsync() { fs.writeFileSync(npmrc, cfg) } - const latest = branch == "master" ? "latest" : "git-" + branch - // upload locs on build on master - const masterOrReleaseBranchRx = /^(master|v\d+\.\d+\.\d+)$/; - const apiStringBranchRx = pxt.appTarget.uploadApiStringsBranchRx - ? new RegExp(pxt.appTarget.uploadApiStringsBranchRx) - : masterOrReleaseBranchRx; + const defaultBranch = pxt.github.isDefaultBranch(branch) + const latest = defaultBranch ? "latest" : "git-" + branch + // upload locs on build on default or releases + const apiStringBranchRx: (t: string) => boolean = ((t:string) => new RegExp(pxt.appTarget.uploadApiStringsBranchRx).test(t)) + ? ((t: string) => new RegExp(pxt.appTarget.uploadApiStringsBranchRx).test(t)) + : ((t: string) => pxt.github.isDefaultOrReleaseBranch(t)); const uploadDocs = !pullRequest && !!pxt.appTarget.uploadDocs - && masterOrReleaseBranchRx.test(branch); + && pxt.github.isDefaultOrReleaseBranch(branch); const uploadApiStrings = !pullRequest && (!!pxt.appTarget.uploadDocs || pxt.appTarget.uploadApiStringsBranchRx) - && apiStringBranchRx.test(branch); + && apiStringBranchRx(branch); pxt.log(`tag: ${tag}`); pxt.log(`branch: ${branch}`); @@ -432,7 +432,7 @@ function ciAsync() { .then(isTaggedCommit => { pxt.log(`is tagged commit: ${isTaggedCommit}`); let p = npmPublishAsync(); - if (branch === "master" && isTaggedCommit) { + if (defaultBranch && isTaggedCommit) { if (uploadDocs) p = p .then(() => buildWebStringsAsync()) @@ -1588,14 +1588,14 @@ function ciBuildInfo(): CiBuildInfo { pxt.log(`event name: ${eventName}`); - // PR: not on master or not a release number + // PR: not on default or not a release number return { ci: "githubactions", branch, tag, commit, commitUrl: "https://github.com/" + repoSlug + "/commits/" + commit, - pullRequest: !(branch == "master" || /^v\d+\.\d+\.\d+$/.test(tag)) + pullRequest: !pxt.github.isDefaultOrReleaseBranch(branch) } } } @@ -5027,32 +5027,6 @@ function writeProjects(prjs: SavedProject[], outDir: string): string[] { return dirs; } -function cherryPickAsync(parsed: commandParser.ParsedCommand) { - const commit = parsed.args[0]; - const name = parsed.flags["name"] || commit.slice(0, 7); - let majorVersion = parseInt(pxtVersion().split('.')[0]); - const gitAsync = (args: string[]) => nodeutil.spawnAsync({ - cmd: "git", - args - }) - - let branches: string[] = []; - for (let i = majorVersion - 1; i >= 0; --i) branches.push("v" + i); - pxt.log(`cherry picking ${commit} into ${branches.join(', ')}`) - - let p = gitAsync(["pull"]); - branches.forEach(branch => { - const pr = `cp/${branch}${name}`; - p = p.then(() => gitAsync(["checkout", branch])) - .then(() => gitAsync(["pull"])) - .then(() => gitAsync(["checkout", "-b", pr])) - .then(() => gitAsync(["cherry-pick", commit])) - .then(() => gitAsync(["push", "--set-upstream", "origin", pr])); - }) - - return p.catch(() => gitAsync(["checkout", "master"])); -} - function checkDocsAsync(parsed?: commandParser.ParsedCommand): Promise { return internalCheckDocsAsync( true, @@ -6156,21 +6130,6 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key } }, c => pyconv.convertAsync(c.args, !!c.flags["internal"])) - p.defineCommand({ - name: "cherrypick", - aliases: ["cp"], - help: "recursively cherrypicks and push branches", - argString: "", - advanced: true, - flags: { - "name": { - description: "name of the branch", - type: "string", - argument: "name" - } - } - }, cherryPickAsync); - p.defineCommand({ name: "decompile", help: "decompile typescript files", diff --git a/pxtlib/github.ts b/pxtlib/github.ts index b66e7a9d554a..82ae5f9d129d 100644 --- a/pxtlib/github.ts +++ b/pxtlib/github.ts @@ -651,6 +651,16 @@ namespace pxt.github { fork?: boolean; } + export function isDefaultBranch(branch: string, repo?: GitRepo) { + if (repo && repo.defaultBranch) + return branch === repo.defaultBranch; + return /^(main|master)$/.test(branch); + } + + export function isDefaultOrReleaseBranch(branch: string, repo?: GitRepo) { + return isDefaultBranch(branch) || /^v\d+\.\d+\.\d+$/.test(branch); + } + export function listUserReposAsync(): Promise { const q = `{ viewer { From 8ad24796176987c9e592c8dc2b78769b4cb69536 Mon Sep 17 00:00:00 2001 From: peli Date: Fri, 19 Jun 2020 09:45:50 -0700 Subject: [PATCH 02/10] removed masters in cli --- cli/cli.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/cli.ts b/cli/cli.ts index 13530f1a9045..b4d68744e161 100644 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -5529,7 +5529,6 @@ function testGithubPackagesAsync(parsed: commandParser.ParsedCommand): Promise Date: Fri, 19 Jun 2020 09:53:36 -0700 Subject: [PATCH 03/10] clean up explorer --- docs/github-explorer.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/github-explorer.html b/docs/github-explorer.html index d42532e80b01..d3bba99d597a 100644 --- a/docs/github-explorer.html +++ b/docs/github-explorer.html @@ -131,7 +131,7 @@ login } nameWithOwner - object(expression: "master:pxt.json") { + object(expression: "HEAD:pxt.json") { ... on Blob { text } @@ -239,7 +239,7 @@ const url = targets[repo.target].url + `?nocookiebanner=1&${readOnly ? 'controller=1&readonly=1&ws=mem&' : 'editorLayout=ide&nosandbox=1'}#pub:github:` - + repo.nameWithOwner + "#master"; + + repo.nameWithOwner; $("#makecodecolumn").attr("src", url); }) From b4bae1e569ef1583dd2841d9014ddf312b84ed72 Mon Sep 17 00:00:00 2001 From: peli Date: Fri, 19 Jun 2020 10:02:23 -0700 Subject: [PATCH 04/10] more cleanups --- localtypings/pxtarget.d.ts | 2 +- pxtlib/browserutils.ts | 2 +- pxtlib/docsrender.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/localtypings/pxtarget.d.ts b/localtypings/pxtarget.d.ts index d95a01aeec39..d98051f0e969 100644 --- a/localtypings/pxtarget.d.ts +++ b/localtypings/pxtarget.d.ts @@ -63,7 +63,7 @@ declare namespace pxt { compileService?: TargetCompileService; ignoreDocsErrors?: boolean; uploadApiStringsBranchRx?: string; // regular expression to match branches that should upload api strings - uploadDocs?: boolean; // enable uploading to crowdin on master or v* builds + uploadDocs?: boolean; // enable uploading to crowdin on default branch or v* builds variants?: Map; // patches on top of the current AppTarget for different chip variants multiVariants?: string[]; alwaysMultiVariant?: boolean; diff --git a/pxtlib/browserutils.ts b/pxtlib/browserutils.ts index f94ffc3e6f68..b2b35c7257d4 100644 --- a/pxtlib/browserutils.ts +++ b/pxtlib/browserutils.ts @@ -665,7 +665,7 @@ namespace pxt.BrowserUtils { class MemTranslationDb implements ITranslationDb { translations: pxt.Map = {}; key(lang: string, filename: string, branch: string) { - return `${lang}|${filename}|${branch || "master"}`; + return `${lang}|${filename}|${branch || "default"}`; } get(lang: string, filename: string, branch: string): ITranslationDbEntry { return this.translations[this.key(lang, filename, branch)]; diff --git a/pxtlib/docsrender.ts b/pxtlib/docsrender.ts index db81a1ced4bf..12e9a6e9ecb9 100644 --- a/pxtlib/docsrender.ts +++ b/pxtlib/docsrender.ts @@ -531,7 +531,7 @@ namespace pxt.docs { if (opts.repo) markdown += ` \`\`\`package -${opts.repo.name.replace(/^pxt-/, '')}=github:${opts.repo.fullName}#${opts.repo.tag || "master"} +${opts.repo.name.replace(/^pxt-/, '')}=github:${opts.repo.fullName}${opts.repo.tag ? `#${opts.repo.tag}` : ""} \`\`\` `; From 0fbc40aadec48b3b6d9b4b995195433dbc1a5fe3 Mon Sep 17 00:00:00 2001 From: peli Date: Fri, 19 Jun 2020 10:25:34 -0700 Subject: [PATCH 05/10] more cleanup --- localtypings/pxtarget.d.ts | 2 +- pxtlib/github.ts | 2 +- webapp/src/db.ts | 4 ++-- webapp/src/package.ts | 2 +- webapp/src/workspace.ts | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/localtypings/pxtarget.d.ts b/localtypings/pxtarget.d.ts index d98051f0e969..0b02e2bc2712 100644 --- a/localtypings/pxtarget.d.ts +++ b/localtypings/pxtarget.d.ts @@ -210,7 +210,7 @@ declare namespace pxt { codalTarget?: string | { name: string; // "codal-arduino-uno" url: string; // "https://github.com/lancaster-university/codal-arduino-uno" - branch: string; // "master" + branch: string; // "main" type: string; // "git" branches?: pxt.Map; // overrides repo url -> commit sha }; diff --git a/pxtlib/github.ts b/pxtlib/github.ts index 82ae5f9d129d..c3470eee1236 100644 --- a/pxtlib/github.ts +++ b/pxtlib/github.ts @@ -613,7 +613,7 @@ namespace pxt.github { forks: number; open_issues: number; watchers: number; - default_branch: string; // "master", + default_branch: string; score: number; // 6.7371006 // non-github, added to track search request diff --git a/webapp/src/db.ts b/webapp/src/db.ts index f8b66b9c8804..5469e243749e 100644 --- a/webapp/src/db.ts +++ b/webapp/src/db.ts @@ -120,7 +120,7 @@ class GithubDb implements pxt.github.IGithubDb { loadConfigAsync(repopath: string, tag: string): Promise { // don't cache master - if (tag == "master") + if (pxt.github.isDefaultBranch(tag)) return this.mem.loadConfigAsync(repopath, tag); const id = `config-${repopath}-${tag}`; @@ -144,7 +144,7 @@ class GithubDb implements pxt.github.IGithubDb { loadPackageAsync(repopath: string, tag: string): Promise { tag = tag || "master"; // don't cache master - if (tag == "master") + if (pxt.github.isDefaultBranch(tag)) return this.mem.loadPackageAsync(repopath, tag); const id = `pkg-${repopath}-${tag}`; diff --git a/webapp/src/package.ts b/webapp/src/package.ts index d94d35ff3427..07583642b0cd 100644 --- a/webapp/src/package.ts +++ b/webapp/src/package.ts @@ -786,7 +786,7 @@ data.mountVirtualApi("pkg-git-pr", { const ghid = f.getPkgId() == "this" && header && header.githubId; if (!ghid) return Promise.resolve(missing); const parsed = pxt.github.parseRepoId(ghid); - if (!parsed || !parsed.tag || parsed.tag == "master") return Promise.resolve(missing); + if (!parsed || !parsed.tag || pxt.github.isDefaultBranch(parsed.tag)) return Promise.resolve(missing); return pxt.github.findPRNumberforBranchAsync(parsed.fullName, parsed.tag) .catch(e => missing); }, diff --git a/webapp/src/workspace.ts b/webapp/src/workspace.ts index f64fc7677d0b..8c877979bdaa 100644 --- a/webapp/src/workspace.ts +++ b/webapp/src/workspace.ts @@ -548,7 +548,7 @@ export async function prAsync(hd: Header, commitId: string, msg: string) { const branchName = await pxt.github.getNewBranchNameAsync(parsed.fullName, "merge-") await pxt.github.createNewBranchAsync(parsed.fullName, branchName, commitId) const url = await pxt.github.createPRFromBranchAsync(parsed.fullName, parsed.tag, branchName, msg) - // force user back to master - we will instruct them to merge PR in github.com website + // force user back to default branch - we will instruct them to merge PR in github.com website // and sync here to get the changes let headCommit = await pxt.github.getRefAsync(parsed.fullName, parsed.tag) await githubUpdateToAsync(hd, { @@ -638,7 +638,7 @@ export async function commitAsync(hd: Header, options: CommitOptions = {}) { // add compiled javascript to be run in github pages if (pxt.appTarget.appTheme.githubCompiledJs && options.binaryJs - && (!parsed.tag || parsed.tag == "master")) { + && (!parsed.tag || pxt.github.isDefaultBranch(parsed.tag))) { const v = cfg.version || "0.0.0"; const opts: compiler.CompileOptions = { jsMetaVersion: v From cff428004c0da96007b1d81cc0bc251210ac4dff Mon Sep 17 00:00:00 2001 From: pelikhan Date: Sat, 8 May 2021 12:31:00 -0700 Subject: [PATCH 06/10] more default work --- cli/buildengine.ts | 2 +- pxtlib/browserutils.ts | 1 + pxtlib/cpp.ts | 2 +- pxtlib/github.ts | 15 ++++++++------- webapp/src/githubbutton.tsx | 2 +- webapp/src/gitjson.tsx | 28 ++++++++++++++-------------- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/cli/buildengine.ts b/cli/buildengine.ts index 2f82456e7271..95ee1d5e0d6e 100644 --- a/cli/buildengine.ts +++ b/cli/buildengine.ts @@ -411,7 +411,7 @@ function updateCodalBuildAsync() { .then( () => /v\d+/.test(cs.gittag) ? Promise.resolve() : codalGitAsync("pull"), e => - codalGitAsync("checkout", "master") + codalGitAsync("checkout", "master") // leave as master .then(() => codalGitAsync("pull"))) .then(() => codalGitAsync("checkout", cs.gittag)) } diff --git a/pxtlib/browserutils.ts b/pxtlib/browserutils.ts index ce173dbfe80b..b617f18ef4c5 100644 --- a/pxtlib/browserutils.ts +++ b/pxtlib/browserutils.ts @@ -1030,6 +1030,7 @@ namespace pxt.BrowserUtils { } function getTutorialInfoKey(filename: string, branch?: string) { + // TODO: 'main' support return `${filename}|${branch || "master"}`; } diff --git a/pxtlib/cpp.ts b/pxtlib/cpp.ts index 6e856312d6a5..49b84408ff69 100644 --- a/pxtlib/cpp.ts +++ b/pxtlib/cpp.ts @@ -1016,7 +1016,7 @@ namespace pxt.cpp { "libraries": U.values(codalLibraries).map(r => ({ "name": r.project, "url": "https://github.com/" + r.fullName, - "branch": r.tag || "master", + "branch": r.tag || "master", // leave as master "type": "git" })) } diff --git a/pxtlib/github.ts b/pxtlib/github.ts index f43924b2061f..6258ed3cb53e 100644 --- a/pxtlib/github.ts +++ b/pxtlib/github.ts @@ -168,10 +168,10 @@ namespace pxt.github { private proxyWithCdnLoadPackageAsync(repopath: string, tag: string): Promise { // cache lookup - const key = `${repopath}/${tag}`; + const key = `${repopath}/${tag || "default"}`; let res = this.packages[key]; if (res) { - pxt.debug(`github cache ${repopath}/${tag}/text`); + pxt.debug(`github cache ${repopath}/${tag || "default"}/text`); return Promise.resolve(res); } @@ -188,7 +188,8 @@ namespace pxt.github { } async loadConfigAsync(repopath: string, tag: string): Promise { - if (!tag) tag = "master"; + // TODO: cloud support + if (!tag) tag = "default"; // cache lookup const key = `${repopath}/${tag}`; @@ -384,7 +385,7 @@ namespace pxt.github { return (resp.statusCode == 200) } - export async function putFileAsync(repopath: string, path: string, content: string) { + export async function putFileAsync(repopath: string, branch: string, path: string, content: string) { const parsed = parseRepoId(repopath); await ghRequestAsync({ url: `https://api.github.com/repos/${pxt.github.join(parsed.slug, "contents", parsed.fileName, path)}`, @@ -393,7 +394,7 @@ namespace pxt.github { data: { message: lf("Initialize empty repo"), content: btoa(U.toUTF8(content)), - branch: "master" + branch }, successCodes: [201] }) @@ -775,7 +776,7 @@ namespace pxt.github { }).then(v => mkRepo(v)) } - export async function enablePagesAsync(repo: string) { + export async function enablePagesAsync(repo: string, branch: string) { // https://developer.github.com/v3/repos/pages/#enable-a-pages-site // try read status const parsed = parseRepoId(repo); @@ -792,7 +793,7 @@ namespace pxt.github { try { const r = await ghPostAsync(`https://api.github.com/repos/${parsed.slug}/pages`, { source: { - branch: "master", + branch, path: "/" } }, { diff --git a/webapp/src/githubbutton.tsx b/webapp/src/githubbutton.tsx index a01faf9b878c..61e3cdccf747 100644 --- a/webapp/src/githubbutton.tsx +++ b/webapp/src/githubbutton.tsx @@ -66,7 +66,7 @@ export class GithubButton extends sui.UIElement maxLength) displayName = displayName.slice(0, maxLength - 2) + '..'; diff --git a/webapp/src/gitjson.tsx b/webapp/src/gitjson.tsx index 3ba367bc1f7d..f8d5dab53bf1 100644 --- a/webapp/src/gitjson.tsx +++ b/webapp/src/gitjson.tsx @@ -234,7 +234,7 @@ class GithubComponent extends data.Component { })) // only branch from master... - if (gid.tag == "master") { + if (pxt.github.isDefaultBranch(gid.tag)) { branchList.unshift({ name: lf("Create new branch"), description: lf("Based on {0}", gid.tag), @@ -749,7 +749,7 @@ class GithubComponent extends data.Component { const hasissue = pullStatus == workspace.PullStatus.BranchNotFound || pullStatus == workspace.PullStatus.NoSourceControl; const haspull = pullStatus == workspace.PullStatus.GotChanges; const githubId = this.parsedRepoId() - const master = githubId.tag == "master"; + const isDefaultBranch = pxt.github.isDefaultBranch(githubId.tag); const user = this.getData("github:user") as pxt.editor.UserInfo; // don't use gs.prUrl, as it gets cleared often @@ -757,7 +757,7 @@ class GithubComponent extends data.Component { const needsToken = !pxt.github.token; // this will show existing PR if any const pr: pxt.github.PullRequest = this.getData("pkg-git-pr:" + header.id) - const showPr = pr !== null && (gs.isFork || !master); + const showPr = pr !== null && (gs.isFork || !isDefaultBranch); const showPrResolved = showPr && pr && pr.number > 0; const showPrCreate = showPr && pr && pr.number <= 0; const isOwner = user && user.id === githubId.owner; @@ -778,7 +778,7 @@ class GithubComponent extends data.Component { - +
{showPrResolved && { {githubId.fullName} {"#" + githubId.tag} - {needsCommit && } - {showPrResolved && !needsCommit && } + {needsCommit && } + {showPrResolved && !needsCommit && } {diffFiles && } - - {master && } - {!isBlocksMode && } + + {isDefaultBranch && } + {!isBlocksMode && }
@@ -1207,7 +1207,7 @@ class MessageComponent extends sui.StatelessUIElement { interface GitHubViewProps { githubId: pxt.github.ParsedRepo; needsToken: boolean; - master: boolean; + isDefaultBranch: boolean; parent: GithubComponent; gs: pxt.github.GitJson; isBlocks: boolean; @@ -1357,7 +1357,7 @@ class ReleaseZone extends sui.StatelessUIElement { private handleBumpClick(e: React.MouseEvent) { pxt.tickEvent("github.releasezone.bump", undefined, { interactiveConsent: true }); e.stopPropagation(); - const { needsCommit, master } = this.props; + const { needsCommit, isDefaultBranch } = this.props; const header = this.props.parent.props.parent.state.header; if (needsCommit) core.confirmAsync({ @@ -1366,10 +1366,10 @@ class ReleaseZone extends sui.StatelessUIElement { agreeLbl: lf("Ok"), hideAgree: true }); - else if (!master) + else if (!isDefaultBranch) core.confirmAsync({ - header: lf("Checkout the master branch..."), - body: lf("You need to checkout the master branch to create a release."), + header: lf("Checkout the default branch..."), + body: lf("You need to checkout the default branch to create a release."), agreeLbl: lf("Ok"), hideAgree: true }); From aa6f22a2d46e127421aa764c90ffff83aff47c79 Mon Sep 17 00:00:00 2001 From: pelikhan Date: Sun, 9 May 2021 07:58:30 -0700 Subject: [PATCH 07/10] more asserts --- pxtlib/github.ts | 24 ++++++++++++++---------- webapp/src/db.ts | 3 ++- webapp/src/dialogs.tsx | 2 +- webapp/src/githubbutton.tsx | 11 +++++------ webapp/src/gitjson.tsx | 12 +++++++----- webapp/src/workspace.ts | 31 +++++++++++++++++++------------ 6 files changed, 48 insertions(+), 35 deletions(-) diff --git a/pxtlib/github.ts b/pxtlib/github.ts index 6258ed3cb53e..34274e3c2167 100644 --- a/pxtlib/github.ts +++ b/pxtlib/github.ts @@ -188,9 +188,7 @@ namespace pxt.github { } async loadConfigAsync(repopath: string, tag: string): Promise { - // TODO: cloud support - if (!tag) tag = "default"; - + U.assert(!!tag) // cache lookup const key = `${repopath}/${tag}`; let res = this.configs[key]; @@ -215,7 +213,7 @@ namespace pxt.github { } async loadPackageAsync(repopath: string, tag: string): Promise { - if (!tag) tag = "master"; + U.assert(!!tag) // try using github proxy first if (hasProxy()) { @@ -452,7 +450,7 @@ namespace pxt.github { } export function getRefAsync(repopath: string, branch: string) { - branch = branch || "master"; + U.assert(!!branch) return ghGetJsonAsync("https://api.github.com/repos/" + repopath + "/git/refs/heads/" + branch) .then(resolveRefAsync) .catch(err => { @@ -564,7 +562,8 @@ namespace pxt.github { .then(resolveRefAsync)) } - export function pkgConfigAsync(repopath: string, tag = "master") { + export function pkgConfigAsync(repopath: string, tag: string) { + U.assert(!!tag) return db.loadConfigAsync(repopath, tag) } @@ -922,7 +921,12 @@ namespace pxt.github { } // try github apis const r = await ghGetJsonAsync("https://api.github.com/repos/" + rid.slug) - return mkRepo(r, { config, fullName: rid.fullName, fileName: rid.fileName, tag: rid.tag }); + return mkRepo(r, { + config, + fullName: rid.fullName, + fileName: rid.fileName, + tag: rid.tag, + }); } function proxyRepoAsync(rid: ParsedRepo, status: GitRepoStatus): Promise { @@ -938,7 +942,7 @@ namespace pxt.github { slug: rid.slug, name: rid.fileName ? `${meta.name}-${rid.fileName}` : meta.name, description: meta.description, - defaultBranch: meta.defaultBranch || "master", + defaultBranch: meta.defaultBranch || "default", // TODO: cloud support tag: rid.tag, status }; @@ -1023,13 +1027,13 @@ namespace pxt.github { } export function stringifyRepo(p: ParsedRepo) { - return p ? "github:" + p.fullName.toLowerCase() + "#" + (p.tag || "master") : undefined; + return p ? "github:" + p.fullName.toLowerCase() + "#" + (p.tag || "default") : undefined; } export function normalizeRepoId(id: string) { const gid = parseRepoId(id); if (!gid) return undefined; - gid.tag = gid.tag || "master"; + gid.tag = gid.tag || "default"; return stringifyRepo(gid); } diff --git a/webapp/src/db.ts b/webapp/src/db.ts index 7691c1144d7a..cb73ad948666 100644 --- a/webapp/src/db.ts +++ b/webapp/src/db.ts @@ -96,6 +96,7 @@ class GithubDb implements pxt.github.IGithubDb { private table = new Table("github"); loadConfigAsync(repopath: string, tag: string): Promise { + pxt.U.assert(!!tag) // don't cache master if (pxt.github.isDefaultBranch(tag)) return this.mem.loadConfigAsync(repopath, tag); @@ -119,7 +120,7 @@ class GithubDb implements pxt.github.IGithubDb { ); } loadPackageAsync(repopath: string, tag: string): Promise { - tag = tag || "master"; + pxt.U.assert(!!tag) // don't cache master if (pxt.github.isDefaultBranch(tag)) return this.mem.loadPackageAsync(repopath, tag); diff --git a/webapp/src/dialogs.tsx b/webapp/src/dialogs.tsx index e236420a9de7..77dc6f6e6517 100644 --- a/webapp/src/dialogs.tsx +++ b/webapp/src/dialogs.tsx @@ -81,7 +81,7 @@ function renderCompileLink(variantName: string, cs: pxt.TargetCompileService) { if (typeof cs.codalTarget === "object" && typeof cs.codalTarget.url === "string") { url = cs.codalTarget.branch ? pxt.BrowserUtils.joinURLs(cs.codalTarget.url, "releases/tag", cs.codalTarget.branch) : cs.codalTarget.url; - version = cs.codalTarget.branch || "master"; + version = cs.codalTarget.branch || "master"; // leave as "master" name = cs.codalTarget.name || cs.serviceId; } else { diff --git a/webapp/src/githubbutton.tsx b/webapp/src/githubbutton.tsx index 61e3cdccf747..7a9d6f147202 100644 --- a/webapp/src/githubbutton.tsx +++ b/webapp/src/githubbutton.tsx @@ -63,7 +63,7 @@ export class GithubButton extends sui.UIElement {displayName} - + ; } } diff --git a/webapp/src/gitjson.tsx b/webapp/src/gitjson.tsx index f8d5dab53bf1..dbdee20acae9 100644 --- a/webapp/src/gitjson.tsx +++ b/webapp/src/gitjson.tsx @@ -693,7 +693,9 @@ class GithubComponent extends data.Component { ` */ - const id = await pxt.github.createPRFromBranchAsync(gh.slug, "master", gh.tag, title, msg); + const packagesConfig = await pxt.packagesConfigAsync() + const repo = await pxt.github.repoAsync(gh.slug, packagesConfig) + const id = await pxt.github.createPRFromBranchAsync(gh.slug, repo.defaultBranch, gh.tag, title, msg); data.invalidateHeader("pkg-git-pr", this.props.parent.state.header); core.infoNotification(lf("Pull request created successfully!", id)); } catch (e) { @@ -753,7 +755,7 @@ class GithubComponent extends data.Component { const user = this.getData("github:user") as pxt.editor.UserInfo; // don't use gs.prUrl, as it gets cleared often - const url = `https://github.com/${githubId.slug}/${master && !githubId.fileName ? "" : pxt.github.join("tree", githubId.tag || "master", githubId.fileName)}`; + const url = `https://github.com/${githubId.slug}}`; const needsToken = !pxt.github.token; // this will show existing PR if any const pr: pxt.github.PullRequest = this.getData("pkg-git-pr:" + header.id) @@ -1142,8 +1144,8 @@ ${content} {displayDiffFiles.map(df => this.showDiff(df))} :
- {lf("No local changes found.")} -
; + {lf("No local changes found.")} + ; } } @@ -1156,7 +1158,7 @@ class MessageComponent extends sui.StatelessUIElement { private handleSwitchMasterBranch(e: React.MouseEvent) { pxt.tickEvent("github.branch.switch"); e.stopPropagation(); - this.props.parent.switchBranchAsync("master"); + this.props.parent.switchBranchAsync("default"); } renderCore() { diff --git a/webapp/src/workspace.ts b/webapp/src/workspace.ts index 6be5af7a0114..f73c8909247e 100644 --- a/webapp/src/workspace.ts +++ b/webapp/src/workspace.ts @@ -370,7 +370,7 @@ interface ProjectChanges { header: Change[], files: Change[], } -function computeChangeSummary(a: {header: Header, text: ScriptText}, b: {header: Header, text: ScriptText}): ProjectChanges { +function computeChangeSummary(a: { header: Header, text: ScriptText }, b: { header: Header, text: ScriptText }): ProjectChanges { const aHdr = a.header || {} as Header const bHdr = b.header || {} as Header const aTxt = a.text || {} @@ -383,22 +383,22 @@ function computeChangeSummary(a: {header: Header, text: ScriptText}, b: {header: const hasHdrChanged = (k: HeaderK) => hasObjChanged(aHdr[k], bHdr[k]) const hdrChanges = hdrKeys.filter(hasHdrChanged) const hdrDels = hdrChanges.filter(k => (k in aHdr) && !(k in bHdr)) - .map(k => ({kind: 'del', key: k, oldVal: aHdr[k]}) as Change) + .map(k => ({ kind: 'del', key: k, oldVal: aHdr[k] }) as Change) const hdrAdds = hdrChanges.filter(k => !(k in aHdr) && (k in bHdr)) - .map(k => ({kind: 'add', key: k, newVal: bHdr[k]}) as Change) + .map(k => ({ kind: 'add', key: k, newVal: bHdr[k] }) as Change) const hdrMods = hdrChanges.filter(k => (k in aHdr) && (k in bHdr)) - .map(k => ({kind: 'mod', key: k, oldVal: aHdr[k], newVal: bHdr[k]}) as Change) + .map(k => ({ kind: 'mod', key: k, oldVal: aHdr[k], newVal: bHdr[k] }) as Change) // files const filenames = U.unique([...Object.keys(aTxt), ...Object.keys(bTxt)], s => s) const hasFileChanged = (filename: string) => aTxt[filename] !== bTxt[filename] const fileChanges = filenames.filter(hasFileChanged) const fileDels = fileChanges.filter(k => (k in aTxt) && !(k in bTxt) && !!b.text) - .map(k => ({kind: 'del', key: k, oldVal: aTxt[k].length}) as Change) + .map(k => ({ kind: 'del', key: k, oldVal: aTxt[k].length }) as Change) const fileAdds = fileChanges.filter(k => !(k in aTxt) && (k in bTxt)) - .map(k => ({kind: 'add', key: k, newVal: bTxt[k].length}) as Change) + .map(k => ({ kind: 'add', key: k, newVal: bTxt[k].length }) as Change) const fileMods = fileChanges.filter(k => (k in aTxt) && (k in bTxt)) - .map(k => ({kind: 'mod', key: k, oldVal: aTxt[k].length, newVal: bTxt[k].length}) as Change) + .map(k => ({ kind: 'mod', key: k, oldVal: aTxt[k].length, newVal: bTxt[k].length }) as Change) return { header: [...hdrDels, ...hdrAdds, ...hdrMods], @@ -408,7 +408,7 @@ function computeChangeSummary(a: {header: Header, text: ScriptText}, b: {header: // useful for debugging function stringifyChangeSummary(diff: ProjectChanges): string { const indent = (s: string) => '\t' + s - const changeToStr = (c: Change) => `${c.kind} ${c.key}: (${c.oldVal || ''}) => (${c.newVal || ''})` + const changeToStr = (c: Change) => `${c.kind} ${c.key}: (${c.oldVal || ''}) => (${c.newVal || ''})` let res = '' const hdrDels = diff.header.filter(k => k.kind === 'del') @@ -442,7 +442,7 @@ export async function partialSaveAsync(id: string, filename: string, content: st pxt.tickEvent(`workspace.invalidSaveToUnknownProject`); return; } - const newTxt = {...await getTextAsync(id)} + const newTxt = { ...await getTextAsync(id) } newTxt[filename] = content; return saveAsync(prev.header, newTxt); } @@ -479,7 +479,7 @@ export async function saveAsync(h: Header, text?: ScriptText, fromCloudSync?: bo return true } const prevProj = e - const allChanges = computeChangeSummary(prevProj, {header: h, text}) + const allChanges = computeChangeSummary(prevProj, { header: h, text }) const ignoredFiles = [GIT_JSON, pxt.SIMSTATE_JSON, pxt.SERIAL_EDITOR_FILE] const ignoredHeaderFields: (keyof Header)[] = ['recentUse', 'modificationTime', 'cloudCurrent', '_rev', '_id' as keyof Header, 'cloudVersion'] const userChanges: ProjectChanges = { @@ -1434,7 +1434,7 @@ export async function initializeGithubRepoAsync(hd: Header, repoid: string, forc // try enable github pages try { - await pxt.github.enablePagesAsync(parsed.slug); + await pxt.github.enablePagesAsync(parsed.slug, parsed.tag); } catch (e) { pxt.reportException(e); } @@ -1450,7 +1450,14 @@ export async function importGithubAsync(id: string): Promise
{ let isEmpty = false let forceTemplateFiles = false; try { + const packagesConfig = await pxt.packagesConfigAsync() + const repo = await pxt.github.repoAsync(parsed.slug, packagesConfig) + if (!repo) + U.userError(`unable to find repository`) + parsed.tag = repo.defaultBranch sha = await pxt.github.getRefAsync(parsed.slug, parsed.tag) + if (!sha) + U.userError(`unable to find branch`) // if the repo does not have a pxt.json file, treat as empty // (must be done before) const commit = await pxt.github.getCommitAsync(parsed.slug, sha) @@ -1620,7 +1627,7 @@ export function fireEvent(ev: pxt.editor.events.Event) { } // debug helpers -const _abrvStrs: {[key: string]: string} = {}; +const _abrvStrs: { [key: string]: string } = {}; let _abrvNextInt = 1; function dbgShorten(s: string): string { if (!s) From 35cd2b318720349068bc5160492901852c158bd8 Mon Sep 17 00:00:00 2001 From: pelikhan Date: Tue, 11 May 2021 09:50:21 -0700 Subject: [PATCH 08/10] fix build --- cli/cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cli.ts b/cli/cli.ts index c2064847ef55..148de32cd9b9 100644 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -279,7 +279,7 @@ function pkginfoAsync(repopath: string) { pxt.debug(`size: ${JSON.stringify(pkg.files).length}`) }) - return pxt.github.pkgConfigAsync(parsed.fullName) + return pxt.github.pkgConfigAsync(parsed.fullName, "default") .then(cfg => { pkgInfo(cfg) return pxt.github.listRefsAsync(repopath) From a369318564ef802274a5f40d4a517e2c1cf38197 Mon Sep 17 00:00:00 2001 From: pelikhan Date: Tue, 11 May 2021 10:20:27 -0700 Subject: [PATCH 09/10] more default branch fixes --- cli/cli.ts | 43 ----------------------------------------- pxtlib/github.ts | 12 +++++++++--- webapp/src/data.ts | 2 +- webapp/src/gitjson.tsx | 2 +- webapp/src/workspace.ts | 13 +++++++++---- 5 files changed, 20 insertions(+), 52 deletions(-) diff --git a/cli/cli.ts b/cli/cli.ts index 148de32cd9b9..8eb0c570d6d3 100644 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -251,49 +251,6 @@ function searchAsync(...query: string[]) { }) } -function pkginfoAsync(repopath: string) { - let parsed = pxt.github.parseRepoId(repopath) - if (!parsed) { - console.log('Unknown repo'); - return Promise.resolve(); - } - - const pkgInfo = (cfg: pxt.PackageConfig, tag?: string) => { - pxt.log(`name: ${cfg.name}`) - pxt.log(`description: ${cfg.description}`) - if (pxt.appTarget.appTheme) - pxt.log(`shareable url: ${pxt.appTarget.appTheme.embedUrl}#pub:gh/${parsed.fullName}${tag ? "#" + tag : ""}`) - } - - return pxt.packagesConfigAsync() - .then(config => { - const status = pxt.github.repoStatus(parsed, config); - pxt.log(`github org: ${parsed.owner}`); - if (parsed.tag) pxt.log(`github tag: ${parsed.tag}`); - pxt.log(`package status: ${status == pxt.github.GitRepoStatus.Approved ? "approved" : status == pxt.github.GitRepoStatus.Banned ? "banned" : "neutral"}`) - if (parsed.tag) - return pxt.github.downloadPackageAsync(repopath, config) - .then(pkg => { - let cfg: pxt.PackageConfig = JSON.parse(pkg.files[pxt.CONFIG_NAME]) - pkgInfo(cfg, parsed.tag) - pxt.debug(`size: ${JSON.stringify(pkg.files).length}`) - }) - - return pxt.github.pkgConfigAsync(parsed.fullName, "default") - .then(cfg => { - pkgInfo(cfg) - return pxt.github.listRefsAsync(repopath) - .then(tags => { - pxt.log("tags: " + tags.join(", ")) - return pxt.github.listRefsAsync(repopath, "heads") - }) - .then(heads => { - pxt.log("branches: " + heads.join(", ")) - }) - }) - }) -} - export function pokeRepoAsync(parsed: commandParser.ParsedCommand): Promise { const repo = parsed.args[0]; diff --git a/pxtlib/github.ts b/pxtlib/github.ts index 34274e3c2167..677196f8ed47 100644 --- a/pxtlib/github.ts +++ b/pxtlib/github.ts @@ -166,7 +166,7 @@ namespace pxt.github { private configs: pxt.Map = {}; private packages: pxt.Map = {}; - private proxyWithCdnLoadPackageAsync(repopath: string, tag: string): Promise { + private async proxyWithCdnLoadPackageAsync(repopath: string, tag: string): Promise { // cache lookup const key = `${repopath}/${tag || "default"}`; let res = this.packages[key]; @@ -177,8 +177,14 @@ namespace pxt.github { // load and cache const parsed = parseRepoId(repopath) - return ghProxyWithCdnJsonAsync(join(parsed.slug, tag, parsed.fileName, "text")) - .then(v => this.packages[key] = { files: v }); + if (!tag || tag === "default") { + // resolve master vs main + const repo: { defaultBranch: string } = await ghProxyWithCdnJsonAsync(parsed.slug) + tag = repo.defaultBranch + } + const v = await ghProxyWithCdnJsonAsync(join(parsed.slug, tag, parsed.fileName, "text")) + const r = this.packages[key] = { files: v } + return r; } private cacheConfig(key: string, v: string) { diff --git a/webapp/src/data.ts b/webapp/src/data.ts index 1b06db8afac6..81ecf975493b 100644 --- a/webapp/src/data.ts +++ b/webapp/src/data.ts @@ -66,7 +66,7 @@ mountVirtualApi("gh-search", { mountVirtualApi("gh-pkgcfg", { getAsync: query => - pxt.github.pkgConfigAsync(stripProtocol(query)).catch(core.handleNetworkError), + pxt.github.pkgConfigAsync(stripProtocol(query), "default").catch(core.handleNetworkError), expirationTime: p => 60 * 1000, isOffline: () => !Cloud.isOnline(), }) diff --git a/webapp/src/gitjson.tsx b/webapp/src/gitjson.tsx index dbdee20acae9..3c9ac1f8b03d 100644 --- a/webapp/src/gitjson.tsx +++ b/webapp/src/gitjson.tsx @@ -1155,7 +1155,7 @@ class MessageComponent extends sui.StatelessUIElement { this.handleSwitchMasterBranch = this.handleSwitchMasterBranch.bind(this); } - private handleSwitchMasterBranch(e: React.MouseEvent) { + private async handleSwitchMasterBranch(e: React.MouseEvent) { pxt.tickEvent("github.branch.switch"); e.stopPropagation(); this.props.parent.switchBranchAsync("default"); diff --git a/webapp/src/workspace.ts b/webapp/src/workspace.ts index f73c8909247e..d35b13e4e341 100644 --- a/webapp/src/workspace.ts +++ b/webapp/src/workspace.ts @@ -966,10 +966,10 @@ export async function commitAsync(hd: Header, options: CommitOptions = {}) { files, saveTag: options.createRelease }) - if (options.createRelease) { + if (options.createRelease && pxt.github.isDefaultBranch(parsed.tag)) { await pxt.github.createReleaseAsync(parsed.slug, options.createRelease, newCommit) // ensure pages are on - await pxt.github.enablePagesAsync(parsed.slug); + await pxt.github.enablePagesAsync(parsed.slug, parsed.tag); // clear the cloud cache await pxt.github.listRefsAsync(parsed.slug, "tags", true, true); } @@ -1218,7 +1218,12 @@ async function githubUpdateToAsync(hd: Header, options: UpdateOptions) { export async function exportToGithubAsync(hd: Header, repoid: string) { const parsed = pxt.github.parseRepoId(repoid); const pfiles = pxt.template.packageFiles(hd.name); - await pxt.github.putFileAsync(parsed.fullName, ".gitignore", pfiles[".gitignore"]); + if (!parsed.tag) { + const packagesConfig = await pxt.packagesConfigAsync() + const repo = await pxt.github.repoAsync(parsed.slug, packagesConfig) + parsed.tag = repo.defaultBranch + } + await pxt.github.putFileAsync(parsed.fullName, parsed.tag, ".gitignore", pfiles[".gitignore"]); const sha = await pxt.github.getRefAsync(parsed.slug, parsed.tag) const commit = await pxt.github.getCommitAsync(parsed.slug, sha) const files = await getTextAsync(hd.id) @@ -1487,7 +1492,7 @@ export async function importGithubAsync(id: string): Promise
{ if (pxt.shell.isReadOnly()) U.userError(lf("This repository looks empty.")); await cloudsync.ensureGitHubTokenAsync(); - await pxt.github.putFileAsync(parsed.fullName, ".gitignore", "# Initial\n"); + await pxt.github.putFileAsync(parsed.fullName, parsed.tag, ".gitignore", "# Initial\n"); isEmpty = true; forceTemplateFiles = true; sha = await pxt.github.getRefAsync(parsed.slug, parsed.tag) From 46a9ac9c805c5be5ccc1425ad19c19e7c8bf3d9c Mon Sep 17 00:00:00 2001 From: pelikhan Date: Tue, 11 May 2021 12:01:33 -0700 Subject: [PATCH 10/10] more mangling with default branch --- pxtlib/github.ts | 5 +++-- webapp/src/data.ts | 7 +++++-- webapp/src/gitjson.tsx | 13 ++++++++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/pxtlib/github.ts b/pxtlib/github.ts index 677196f8ed47..083460e5e88e 100644 --- a/pxtlib/github.ts +++ b/pxtlib/github.ts @@ -948,7 +948,7 @@ namespace pxt.github { slug: rid.slug, name: rid.fileName ? `${meta.name}-${rid.fileName}` : meta.name, description: meta.description, - defaultBranch: meta.defaultBranch || "default", // TODO: cloud support + defaultBranch: meta.defaultBranch, tag: rid.tag, status }; @@ -1039,7 +1039,8 @@ namespace pxt.github { export function normalizeRepoId(id: string) { const gid = parseRepoId(id); if (!gid) return undefined; - gid.tag = gid.tag || "default"; + // this does not work anymore + gid.tag = gid.tag; return stringifyRepo(gid); } diff --git a/webapp/src/data.ts b/webapp/src/data.ts index 81ecf975493b..c04efddc2327 100644 --- a/webapp/src/data.ts +++ b/webapp/src/data.ts @@ -64,12 +64,14 @@ mountVirtualApi("gh-search", { isOffline: () => !Cloud.isOnline(), }) +/* does not seem to be used mountVirtualApi("gh-pkgcfg", { getAsync: query => - pxt.github.pkgConfigAsync(stripProtocol(query), "default").catch(core.handleNetworkError), + pxt.github.pkgConfigAsync(stripProtocol(query), ).catch(core.handleNetworkError), expirationTime: p => 60 * 1000, isOffline: () => !Cloud.isOnline(), }) +*/ // gh-commits:repo#sha mountVirtualApi("gh-commits", { @@ -95,7 +97,8 @@ mountVirtualApi("target-config", { pxt.storage.setLocal("targetconfig", JSON.stringify(js)) invalidate("target-config"); invalidate("gh-search"); - invalidate("gh-pkgcfg"); + // does not seem to be used + // invalidate("gh-pkgcfg"); } return js; }) diff --git a/webapp/src/gitjson.tsx b/webapp/src/gitjson.tsx index 3c9ac1f8b03d..68daf0af9f14 100644 --- a/webapp/src/gitjson.tsx +++ b/webapp/src/gitjson.tsx @@ -165,10 +165,17 @@ class GithubComponent extends data.Component { await f.setContentAsync(JSON.stringify(gs, null, 4)) } - private async switchProjectToBranchAsync(newBranch: string) { + private async switchProjectToBranchAsync(newBranch?: string) { const { header } = this.props.parent.state; const gs = this.getGitJson(); const parsed = this.parsedRepoId() + + if (!newBranch) { + const packagesConfig = await pxt.packagesConfigAsync() + const repo = await pxt.github.repoAsync(parsed.slug, packagesConfig) + newBranch = repo.defaultBranch + } + header.githubId = parsed.fullName + "#" + newBranch gs.repo = header.githubId await this.saveGitJsonAsync(gs) @@ -208,7 +215,7 @@ class GithubComponent extends data.Component { } } - public async switchBranchAsync(branch: string) { + public async switchBranchAsync(branch?: string) { await this.setStateAsync({ needsCommitMessage: false }); const prevBranch = this.parsedRepoId().tag try { @@ -1158,7 +1165,7 @@ class MessageComponent extends sui.StatelessUIElement { private async handleSwitchMasterBranch(e: React.MouseEvent) { pxt.tickEvent("github.branch.switch"); e.stopPropagation(); - this.props.parent.switchBranchAsync("default"); + this.props.parent.switchBranchAsync(); } renderCore() {