Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[server] Infer config for non-configured repositories #7383

Merged
merged 2 commits into from
Dec 30, 2021
Merged

Conversation

svenefftinge
Copy link
Member

@svenefftinge svenefftinge commented Dec 29, 2021

This change will use the configuration inference for all workspaces as the fallback.

fixes #6921

Testing

Start a workspace on a repository without a .gitpod.yml and find a derived .gitpod.yml in the opened workspace.

Release Notes

Automatically propose a configuration for non-configured repositories.

@svenefftinge svenefftinge changed the title [WIP] infer config [server] Infer config for non-configured repositories Dec 29, 2021
@svenefftinge
Copy link
Member Author

svenefftinge commented Dec 29, 2021

/werft run

👍 started the job as gitpod-build-se-init.4

@svenefftinge
Copy link
Member Author

svenefftinge commented Dec 29, 2021

/werft run

👍 started the job as gitpod-build-se-init.5

@svenefftinge
Copy link
Member Author

svenefftinge commented Dec 29, 2021

/werft run

👍 started the job as gitpod-build-se-init.6

@svenefftinge
Copy link
Member Author

svenefftinge commented Dec 29, 2021

/werft run

👍 started the job as gitpod-build-se-init.8

Copy link
Contributor

@gtsiolis gtsiolis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UX works like a charm and definitely improves the onboarding experience for non-configured repos. 🔮

Left one minor comment (issue) which could be tackled separately. ❗

🍊 🍊 🍊 🍊

Wondering if there’s anything if could do to improve feature (auto-detection and file generation) visibility here and make it less surprising to users when they find out about the new untracked .gitpod.yml file. Probably fine to do also out of the scope of this PR in the spirit of MVC (minimum viable change). ➿

For example, we could:

  1. Add an additional comment in the generated .gtipod.yml to describe what this file is and how to change it by linking to relevant docs.
  2. Trigger (yet) another notification inside the editor to inform the user about project detection with an action to open the .gitpod.yml.
  3. Inform the user about project type detection during workspace loading (workspace start page) for authorized users and during login for anonymous users.

Successful project detection is something we could also surface when the project is added, in #7271. 💡 Cc @jldec

🍋 🍋 🍋 🍋

Approving to unblock merging but holding in case someone from the team could take a closer look at the code changes. 👀

/hold

}
}

if (!customConfig) {
return undefined;
}

return { customConfig, configBasePath };
return { customConfig, configBasePath, literalConfig: { '.gitpod.yml': customConfigString || ''} };
Copy link
Contributor

@gtsiolis gtsiolis Dec 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue(non-blocking): Probably not the best line to add this comment (😅) but is it expected that the new untracked auto-generated .gitpod.yml is not visible as changelist in the workspaces list when the workspace stops?

Workspaces with new auto-generated .gitpod.yml and one file change
Screenshot 2021-12-29 at 11 26 37 PM

Copy link
Member Author

@svenefftinge svenefftinge Dec 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty unrelated and should work as reliable as it does with other pending changes.
Related issue #7370

@roboquat
Copy link
Contributor

LGTM label has been added.

Git tree hash: 6558a64c319c3a6cd6f31611246262722344d43a

@svenefftinge
Copy link
Member Author

  1. Add an additional comment in the generated .gtipod.yml

That makes a ton of sense. We could also build a VS Code extension for .gitpod.yml files that sports code lenses and easy access to documentation. Adding a comment if definitely the lower-hanging thing to do. I'd love to do this on a separate PR, though.

Copy link
Contributor

@jankeromnes jankeromnes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned on Slack, wow, this is epic! 🎸

Super clean implementation ✨ the code looks good to me, and works as advertised (I've even tested with an empty repository). 🔥🔥🔥

Bonus points for cleaning up the old code 🧹 (side note: I think we might also want to delete the language detection code in the future).

Also, I think a cool follow-up could be to add a comment to the generated .gitpod.yml file (e.g. to briefly explain what this file is / why it's there).

/approve

Comment on lines +60 to +65
if (typeof contextURLOrContext === 'string') {
const normalizedContextUrl = this.contextParser.normalizeContextURL(contextURLOrContext);
commitContext = (await this.contextParser.handle(ctx, user, normalizedContextUrl)) as CommitContext;
} else {
commitContext = contextURLOrContext;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -57,7 +57,6 @@
"express-mysql-session": "^2.1.0",
"express-session": "^1.15.6",
"fs-extra": "^10.0.0",
"gitpod-yml-inferrer": "^1.2.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines -1 to -72
/**
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License-AGPL.txt in the project root for license information.
*/

import { inject, injectable, postConstruct } from "inversify";
import { CommitContext, User, WorkspaceConfig } from "@gitpod/gitpod-protocol";
import { HostContextProvider } from "../auth/host-context-provider";
import { Config } from "../config";

export type LanguageConfigProvider = (language: string, user: User, commit: CommitContext) => Promise<WorkspaceConfig | undefined>;

@injectable()
export class ConfigInferenceProvider {
@inject(HostContextProvider) protected readonly hostContextProvider: HostContextProvider;
@inject(Config) protected readonly config: Config;

protected readonly languageConfigProvider = new Map<string, LanguageConfigProvider>();

@postConstruct()
public registerLanguageInferrer() {
this.languageConfigProvider.set('Go', this.computeGoConfig.bind(this));
}

public async infer(user: User, commit: CommitContext): Promise<WorkspaceConfig | undefined> {
const host = commit.repository.host;
const hostContext = this.hostContextProvider.get(host);
if (!hostContext || !hostContext.services) {
return undefined;
}
const repoHost = hostContext.services;
const languages = await repoHost.languagesProvider.getLanguages(commit.repository, user);
const topLanguage = this.findTopLanguage(languages);
if (topLanguage === undefined) {
return undefined;
}

const configProvider = this.languageConfigProvider.get(topLanguage);
if (configProvider === undefined) {
return undefined;
}

return configProvider(topLanguage, user, commit);
}

protected findTopLanguage(languages: any) {
let result: string | undefined;
let topScore: number | undefined;
Object.keys(languages).forEach(lang => {
let score = languages[lang];
if (topScore === undefined || score > topScore) {
result = lang;
topScore = score;
}
});
return result;
}

protected async computeGoConfig(lang: String, user: User, commit: CommitContext): Promise<WorkspaceConfig | undefined> {
return {
ports: [],
tasks: [
{
init: `test -f go.mod && go get -v ./...`
}
],
image: this.config.workspaceDefaults.workspaceImage,
} as WorkspaceConfig;
}

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

let customConfigString = await contextRepoConfig;
let fromProjectDB = false;
customConfigString = await contextRepoConfig;
let origin: WorkspaceConfig["_origin"] = 'repo';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if (!customConfigString) {
// if there's still no configuration, let's infer one
customConfigString = await inferredConfig;
origin = "derived";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super-nit: Technically, I think this should be conditional on the inferrer returning something (however, in the current state of the code, this doesn't matter because of the if (!customConfig) { return undefined; } below).

Suggested change
origin = "derived";
if (customConfigString) {
origin = "derived";
}

Comment on lines +155 to +157
if (config._origin === 'derived' && literalConfig) {
(context as any as AdditionalContentContext).additionalFiles = { ... literalConfig };
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@roboquat
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: gtsiolis, jankeromnes

Associated issue: #6921

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@svenefftinge
Copy link
Member Author

/unhold

@roboquat roboquat merged commit 91c09f7 into main Dec 30, 2021
@roboquat roboquat deleted the se/init branch December 30, 2021 13:45
@roboquat roboquat added deployed: webapp Meta team change is running in production deployed Change is completely running in production labels Jan 4, 2022
@jldec jldec mentioned this pull request Feb 27, 2022
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved deployed: webapp Meta team change is running in production deployed Change is completely running in production release-note size/XL team: webapp Issue belongs to the WebApp team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Always Infer .gitpod.yml
4 participants