diff --git a/assets/images/help/settings/cookie-settings-accept-or-reject.png b/assets/images/help/settings/cookie-settings-accept-or-reject.png new file mode 100644 index 000000000000..3c220255fd7c Binary files /dev/null and b/assets/images/help/settings/cookie-settings-accept-or-reject.png differ diff --git a/assets/images/help/settings/cookie-settings-manage.png b/assets/images/help/settings/cookie-settings-manage.png new file mode 100644 index 000000000000..c95b55080a30 Binary files /dev/null and b/assets/images/help/settings/cookie-settings-manage.png differ diff --git a/assets/images/help/settings/cookie-settings-save.png b/assets/images/help/settings/cookie-settings-save.png new file mode 100644 index 000000000000..7a85412d784b Binary files /dev/null and b/assets/images/help/settings/cookie-settings-save.png differ diff --git a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/dotnet.tsx b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/dotnet.tsx index 010d218b1dd1..d04647983ec9 100644 --- a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/dotnet.tsx +++ b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/dotnet.tsx @@ -53,18 +53,26 @@ const article: PlaygroundArticleT = { To set up your repository to use a custom dev container, you will need to create one or more \`devcontainer.json\` files. You can add these either from a template, in Visual Studio Code, or you can write your own. For more information on dev container configurations, see "[Introduction to dev containers](/codespaces/setting-up-your-codespace/configuring-codespaces-for-your-project)". - 1. Access the Command Palette (Shift + Command + P / Ctrl + Shift + P), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. - ![Codespaces: Add Development Container Configuration Files... in the command palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 1. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. + + ![Codespaces: Add Development Container Configuration Files... in the Command Palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 2. For this example, click **C# (.NET)**. If you need additional features you can select any container that’s specific to C# (.NET) or a combination of tools such as C# (.NET) and MS SQL. - ![Select C# (.NET) option from the list](/assets/images/help/codespaces/add-dotnet-prebuilt-container.png) + ![Select C# (.NET) option from the list](/assets/images/help/codespaces/add-dotnet-prebuilt-container.png) + 3. Click the recommended version of .NET. - ![.NET version selection](/assets/images/help/codespaces/add-dotnet-version.png) + + ![.NET version selection](/assets/images/help/codespaces/add-dotnet-version.png) + 4. Accept the default option to add Node.js to your customization. - ![Add Node.js selection](/assets/images/help/codespaces/dotnet-options.png) + + ![Add Node.js selection](/assets/images/help/codespaces/dotnet-options.png) + 5. Select any additional features to install and click **OK**. - 6. Access the command palette (Shift + Command + P / Ctrl + Shift + P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. - ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + 6. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + `, }, { @@ -197,13 +205,16 @@ const article: PlaygroundArticleT = { "postCreateCommand": "dotnet restore", \`\`\` - 4. Access the command palette (\`Shift + Command + P\`/ \`Ctrl + Shift + P\`), then start typing "rebuild". Select **Codespaces: Rebuild Container**. - ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) - Rebuilding inside your codespace ensures your changes work as expected before you commit the changes to the repository. If something does result in a failure, you’ll be placed in a codespace with a recovery container that you can rebuild from to keep adjusting your container. + 4. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + + ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + + Rebuilding inside your codespace ensures your changes work as expected before you commit the changes to the repository. If something does result in a failure, you’ll be placed in a codespace with a recovery container that you can rebuild from to keep adjusting your container. 5. Check your changes were successfully applied by verifying the "Code Spell Checker" extension was installed. - ![Extensions list](/assets/images/help/codespaces/dotnet-extensions.png) + ![Extensions list](/assets/images/help/codespaces/dotnet-extensions.png) + `, }, { @@ -217,9 +228,10 @@ const article: PlaygroundArticleT = { 1. Run your application by pressing \`F5\` or entering \`dotnet watch run\` in your terminal. - 2. When your project starts, you should see a message in the bottom right corner with a prompt to connect to the port your project uses. + 2. When your project starts, you should see a message in the bottom right corner with a prompt to connect to the port your project uses. + + ![Port forwarding toast](/assets/images/help/codespaces/python-port-forwarding.png) - ![Port forwarding toast](/assets/images/help/codespaces/python-port-forwarding.png) `, }, { diff --git a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/java.tsx b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/java.tsx index 6824f820c665..3950e5920fd9 100644 --- a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/java.tsx +++ b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/java.tsx @@ -51,15 +51,23 @@ const article: PlaygroundArticleT = { To set up your repository to use a custom dev container, you will need to create one or more \`devcontainer.json\` files. You can add these either from a template, in Visual Studio Code, or you can write your own. For more information on dev container configurations, see "[Introduction to dev containers](/codespaces/setting-up-your-codespace/configuring-codespaces-for-your-project)". - 1. Access the Command Palette (\`Shift + Command + P\` / \`Ctrl + Shift + P\`), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. - !["Codespaces: Add Development Container Configuration Files..." in the command palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 1. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. + + !["Codespaces: Add Development Container Configuration Files..." in the Command Palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 2. For this example, click **Java**. In practice, you could select any container that’s specific to Java or a combination of tools such as Java and Azure Functions. - ![Select Java option from the list](/assets/images/help/codespaces/add-java-prebuilt-container.png) + + ![Select Java option from the list](/assets/images/help/codespaces/add-java-prebuilt-container.png) + 3. Click the recommended version of Java. - ![Java version selection](/assets/images/help/codespaces/add-java-version.png) + + ![Java version selection](/assets/images/help/codespaces/add-java-version.png) + 4. Select any additional features to install and click **OK**. - 5. Access the command palette (\`Shift + Command + P\`/ \`Ctrl + Shift + P\`), then start typing "rebuild". Select **Codespaces: Rebuild Container**. - ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + 5. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + + ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + `, }, { @@ -185,9 +193,11 @@ const article: PlaygroundArticleT = { For more information about \`devcontainer.json\` properties, see the Visual Studio Code documentation: "[devcontainer.json reference](https://code.visualstudio.com/docs/remote/devcontainerjson-reference)." - 4. Access the command palette (\`Shift + Command + P\`/ \`Ctrl + Shift + P\`), then start typing "rebuild". Select **Codespaces: Rebuild Container**. - ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) - Rebuilding inside your codespace ensures your changes work as expected before you commit the changes to the repository. If something does result in a failure, you’ll be placed in a codespace with a recovery container that you can rebuild from to keep adjusting your container. + 4. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + + ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + + Rebuilding inside your codespace ensures your changes work as expected before you commit the changes to the repository. If something does result in a failure, you’ll be placed in a codespace with a recovery container that you can rebuild from to keep adjusting your container. `, }, { diff --git a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/nodejs.tsx b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/nodejs.tsx index 6667f11234da..eebba23d1f4e 100644 --- a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/nodejs.tsx +++ b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/nodejs.tsx @@ -29,7 +29,7 @@ const article: PlaygroundArticleT = { content: dedent` 1. Under the repository name, use the **Code** drop-down menu, and in the **Codespaces** tab, click **Create codespace on BRANCH**. - ![New codespace button](/assets/images/help/codespaces/new-codespace-button.png) + ![New codespace button](/assets/images/help/codespaces/new-codespace-button.png) If you don’t see this option, GitHub Codespaces isn't available for your project. See [Access to GitHub Codespaces](/codespaces/developing-in-codespaces/creating-a-codespace#access-to-codespaces) for more information. @@ -51,15 +51,23 @@ const article: PlaygroundArticleT = { To set up your repository to use a custom dev container, you will need to create one or more \`devcontainer.json\` files. You can add these either from a template, in Visual Studio Code, or you can write your own. For more information on dev container configurations, see "[Introduction to dev containers](/codespaces/setting-up-your-codespace/configuring-codespaces-for-your-project)". - 1. Access the Command Palette (\`Shift + Command + P\` / \`Ctrl + Shift + P\`), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. - !["Codespaces: Add Development Container Configuration Files..." in the command palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 1. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. + + !["Codespaces: Add Development Container Configuration Files..." in the Command Palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 2. For this example, click **Node.js**. If you need additional features you can select any container that’s specific to Node or a combination of tools such as Node and MongoDB. - ![Select Node option from the list](/assets/images/help/codespaces/add-node-prebuilt-container.png) + + ![Select Node option from the list](/assets/images/help/codespaces/add-node-prebuilt-container.png) + 3. Click the recommended version of Node.js. - ![Node.js version selection](/assets/images/help/codespaces/add-node-version.png) + + ![Node.js version selection](/assets/images/help/codespaces/add-node-version.png) + 4. Select any additional features to install and click **OK**. - 5. Access the command palette (\`Shift + Command + P\`/ \`Ctrl + Shift + P\`), then start typing "rebuild". Select **Codespaces: Rebuild Container**. - ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + 5. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + + ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + `, }, { @@ -173,7 +181,9 @@ const article: PlaygroundArticleT = { With your dev container configuration added and a basic understanding of what everything does, you can now make changes to customize your environment further. In this example, you'll add properties to install npm when your codespace launches and make a list of ports inside the container available locally. 1. In the Explorer, select the \`devcontainer.json\` file from the tree to open it. You might have to expand the \`.devcontainer\` folder to see it. - ![devcontainer.json file in the Explorer](/assets/images/help/codespaces/devcontainers-options.png) + + ![devcontainer.json file in the Explorer](/assets/images/help/codespaces/devcontainers-options.png) + 2. Add the following lines to your \`devcontainer.json\` file after \`extensions\`: \`\`\`js{:copy} @@ -182,10 +192,11 @@ const article: PlaygroundArticleT = { \`\`\` For more information about \`devcontainer.json\` properties, see the Visual Studio Code documentation: "[devcontainer.json reference](https://code.visualstudio.com/docs/remote/devcontainerjson-reference)." - 1. Access the command palette (\`Shift + Command + P\`/ \`Ctrl + Shift + P\`), then start typing "rebuild". Select **Codespaces: Rebuild Container**. - ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + 3. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + + ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) - Rebuilding inside your codespace ensures your changes work as expected before you commit the changes to the repository. If something does result in a failure, you’ll be placed in a codespace with a recovery container that you can rebuild from to keep adjusting your container. + Rebuilding inside your codespace ensures your changes work as expected before you commit the changes to the repository. If something does result in a failure, you’ll be placed in a codespace with a recovery container that you can rebuild from to keep adjusting your container. `, }, { diff --git a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/python.tsx b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/python.tsx index 7bba6a54a8b4..87425b849b27 100644 --- a/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/python.tsx +++ b/components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/python.tsx @@ -29,9 +29,9 @@ const article: PlaygroundArticleT = { content: dedent` 1. Under the repository name, use the **Code** drop-down menu, and in the **Codespaces** tab, click **Create codespace on BRANCH**. - ![New codespace button](/assets/images/help/codespaces/new-codespace-button.png) + ![New codespace button](/assets/images/help/codespaces/new-codespace-button.png) - If you don’t see this option, GitHub Codespaces isn't available for your project. See [Access to GitHub Codespaces](/codespaces/developing-in-codespaces/creating-a-codespace#access-to-codespaces) for more information. + If you don’t see this option, GitHub Codespaces isn't available for your project. See [Access to GitHub Codespaces](/codespaces/developing-in-codespaces/creating-a-codespace#access-to-codespaces) for more information. When you create a codespace, your project is created on a remote VM that is dedicated to you. By default, the container for your codespace has many languages and runtimes including Python, pip, and Miniconda. It also includes a common set of tools like git, wget, rsync, openssh, and nano. @@ -53,17 +53,27 @@ const article: PlaygroundArticleT = { To set up your repository to use a custom dev container, you will need to create one or more \`devcontainer.json\` files. You can add these either from a template, in Visual Studio Code, or you can write your own. For more information on dev container configurations, see "[Introduction to dev containers](/codespaces/setting-up-your-codespace/configuring-codespaces-for-your-project)". - 1. Access the command palette (\`Shift + Command + P\` / \`Ctrl + Shift + P\`), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. - !["Codespaces: Add Development Container Configuration Files..." in the command palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 1. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "dev container". Select **Codespaces: Add Development Container Configuration Files...**. + + !["Codespaces: Add Development Container Configuration Files..." in the Command Palette](/assets/images/help/codespaces/add-prebuilt-container-command.png) + 2. For this example, click **Python 3**. If you need additional features you can select any container that’s specific to Python or a combination of tools such as Python 3 and PostgreSQL. - ![Select Python option from the list](/assets/images/help/codespaces/add-python-prebuilt-container.png) + + ![Select Python option from the list](/assets/images/help/codespaces/add-python-prebuilt-container.png) + 3. Click the recommended version of Python. - ![Python version selection](/assets/images/help/codespaces/add-python-version.png) + + ![Python version selection](/assets/images/help/codespaces/add-python-version.png) + 4. Accept the default option to add Node.js to your customization. - ![Add Node.js selection](/assets/images/help/codespaces/add-nodejs-selection.png) + + ![Add Node.js selection](/assets/images/help/codespaces/add-nodejs-selection.png) + 5. Select any additional features to install and click **OK**. - 6. Access the command palette (\`Shift + Command + P\` / \`Ctrl + Shift + P\`), then start typing "rebuild". Select **Codespaces: Rebuild Container**. - ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + 6. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + + ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) + `, }, { @@ -197,7 +207,7 @@ const article: PlaygroundArticleT = { "postCreateCommand": "pip3 install --user -r requirements.txt", \`\`\` - 4. Access the command palette (\`Shift + Command + P\` / \`Ctrl + Shift + P\`), then start typing "rebuild". Select **Codespaces: Rebuild Container**. + 4. Access the Command Palette (Shift+Command+P / Ctrl+Shift+P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) diff --git a/content/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/index.md b/content/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/index.md index 2f1b6925f778..7a6d7d63205c 100644 --- a/content/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/index.md +++ b/content/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/index.md @@ -25,6 +25,7 @@ children: - /managing-the-default-branch-name-for-your-repositories - /managing-security-and-analysis-settings-for-your-personal-account - /managing-access-to-your-personal-accounts-project-boards + - /managing-your-cookie-preferences-for-githubs-enterprise-marketing-pages - /integrating-jira-with-your-personal-projects - /what-does-the-available-for-hire-checkbox-do shortTitle: Personal account settings diff --git a/content/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/managing-your-cookie-preferences-for-githubs-enterprise-marketing-pages.md b/content/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/managing-your-cookie-preferences-for-githubs-enterprise-marketing-pages.md new file mode 100644 index 000000000000..9f7621f05677 --- /dev/null +++ b/content/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/managing-your-cookie-preferences-for-githubs-enterprise-marketing-pages.md @@ -0,0 +1,33 @@ +--- +title: Managing your cookie preferences for GitHub's enterprise marketing pages +intro: "You can control how {% data variables.product.company_short %} uses information from non-essential tracking cookies for enterprise marketing pages." +versions: + fpt: '*' + ghes: '*' + ghae: '*' + ghec: '*' +topics: + - Accounts +shortTitle: Manage cookie preferences +--- + +## About cookie preferences on enterprise marketing pages + +{% data variables.product.company_short %} may use non-essential cookies on some enterprise marketing pages. You can customize how these cookies behave. For more information about how {% data variables.product.company_short %} uses cookies, see "[{% data variables.product.company_short %} Privacy Statement](/free-pro-team@latest/site-policy/privacy-policies/github-privacy-statement)." + +## Changing your cookie preferences + +You can customize how non-essential cookies behave on any {% data variables.product.company_short %} enterprise marketing page. + +1. Navigate to the {% data variables.product.company_short %} enterprise marketing page where you'd like to change your cookie preferences. For example, navigate to [{% data variables.product.company_short %} Resources](https://resources.github.com/). +1. Scroll to the bottom of the page, then click **Manage Cookies**. + + ![Screenshot of button to manage cookie settings.](/assets/images/help/settings/cookie-settings-manage.png) + +1. Under "Manage cookie preferences," to accept or reject each non-essential cookie, click **Accept** or **Reject**. + + ![Screenshot of radio buttons to choose "Accept" or "Reject" for non-essential cookies.](/assets/images/help/settings/cookie-settings-accept-or-reject.png) + +1. Click **Save changes**. + + ![Screenshot of button to save changes.](/assets/images/help/settings/cookie-settings-save.png) diff --git a/content/codespaces/codespaces-reference/using-the-vs-code-command-palette-in-codespaces.md b/content/codespaces/codespaces-reference/using-the-vs-code-command-palette-in-codespaces.md index bf2b347536e8..a26e5f7ebdde 100644 --- a/content/codespaces/codespaces-reference/using-the-vs-code-command-palette-in-codespaces.md +++ b/content/codespaces/codespaces-reference/using-the-vs-code-command-palette-in-codespaces.md @@ -17,7 +17,7 @@ redirect_from: ## About the {% data variables.product.prodname_vscode_command_palette %} -The Command Palette is one of the focal features of {% data variables.product.prodname_vscode %} and is available for you to use in {% data variables.product.prodname_github_codespaces %}. The {% data variables.product.prodname_vscode_command_palette %} allows you to access many commands for {% data variables.product.prodname_codespaces %} and {% data variables.product.prodname_vscode_shortname %}. For more information on using the {% data variables.product.prodname_vscode_command_palette_shortname %}, see "[User Interface](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette)" in the {% data variables.product.prodname_vscode_shortname %} documentation. +The Command Palette is one of the focal features of {% data variables.product.prodname_vscode %} and is available for you to use in {% data variables.product.prodname_github_codespaces %}. The Command Palette allows you to access many commands for {% data variables.product.prodname_codespaces %} and {% data variables.product.prodname_vscode_shortname %}. For more information on using the {% data variables.product.prodname_vscode_command_palette_shortname %}, see "[User Interface](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette)" in the {% data variables.product.prodname_vscode_shortname %} documentation. ## Accessing the {% data variables.product.prodname_vscode_command_palette_shortname %} diff --git a/content/codespaces/getting-started/deep-dive.md b/content/codespaces/getting-started/deep-dive.md index f22981969a98..b4afca5e51ba 100644 --- a/content/codespaces/getting-started/deep-dive.md +++ b/content/codespaces/getting-started/deep-dive.md @@ -73,7 +73,7 @@ As you develop in your codespace, it will save any changes to your files every f ### Closing or stopping your codespace -To stop your codespace you can [use the {% data variables.product.prodname_vscode_command_palette %}](/codespaces/codespaces-reference/using-the-vs-code-command-palette-in-codespaces#suspending-or-stopping-a-codespace) (`Shift + Command + P` (Mac) / `Ctrl + Shift + P` (Windows)). If you exit your codespace without running the stop command (for example, closing the browser tab), or if you leave the codespace running without interaction, the codespace and its running processes will continue until a window of inactivity occurs, after which the codespace will stop. By default, the window of inactivity is 30 minutes. +To stop your codespace you can [use the {% data variables.product.prodname_vscode_command_palette %}](/codespaces/codespaces-reference/using-the-vs-code-command-palette-in-codespaces#suspending-or-stopping-a-codespace) (Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux)). If you exit your codespace without running the stop command (for example, closing the browser tab), or if you leave the codespace running without interaction, the codespace and its running processes will continue until a window of inactivity occurs, after which the codespace will stop. By default, the window of inactivity is 30 minutes. When you close or stop your codespace, all uncommitted changes are preserved until you connect to the codespace again. diff --git a/content/codespaces/setting-up-your-project-for-codespaces/introduction-to-dev-containers.md b/content/codespaces/setting-up-your-project-for-codespaces/introduction-to-dev-containers.md index 04b6b16f6553..75aed3dcf398 100644 --- a/content/codespaces/setting-up-your-project-for-codespaces/introduction-to-dev-containers.md +++ b/content/codespaces/setting-up-your-project-for-codespaces/introduction-to-dev-containers.md @@ -155,9 +155,9 @@ You can add features to your predefined container configuration to customize whi You can add some of the most common features by selecting them when configuring your predefined container. For more information on the available features, see the [script library](https://github.com/microsoft/vscode-dev-containers/tree/main/script-library#scripts) in the `vscode-dev-containers` repository. -1. Access the Command Palette (`Shift + Command + P` / `Ctrl + Shift + P`), then start typing "configure". Select **Codespaces: Configure Devcontainer Features**. +1. Access the Command Palette (Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux)), then start typing "configure". Select **Codespaces: Configure Devcontainer Features**. - ![The Configure Devcontainer Features command in the command palette](/assets/images/help/codespaces/codespaces-configure-features.png) + ![The Configure Devcontainer Features command in the Command Palette](/assets/images/help/codespaces/codespaces-configure-features.png) 1. Update your feature selections, then click **OK**. @@ -165,7 +165,7 @@ You can add some of the most common features by selecting them when configuring 1. To apply the changes, in the bottom right corner of the screen, click **Rebuild now**. For more information about rebuilding your container, see "[Applying changes to your configuration](#applying-configuration-changes-to-a-codespace)." - !["Codespaces: Rebuild Container" in the command palette](/assets/images/help/codespaces/rebuild-prompt.png) + !["Codespaces: Rebuild Container" in the Command Palette](/assets/images/help/codespaces/rebuild-prompt.png) ## Creating a custom dev container configuration diff --git a/content/codespaces/troubleshooting/github-codespaces-logs.md b/content/codespaces/troubleshooting/github-codespaces-logs.md index 9e69b8ca68f0..737333eefc98 100644 --- a/content/codespaces/troubleshooting/github-codespaces-logs.md +++ b/content/codespaces/troubleshooting/github-codespaces-logs.md @@ -28,7 +28,7 @@ These logs contain detailed information about the codespace, the container, the {% webui %} 1. If you are using {% data variables.product.prodname_codespaces %} in the browser, ensure that you are connected to the codespace you want to debug. -1. Open the {% data variables.product.prodname_vscode %} Command Palette (`Shift + Command + P` (Mac) / `Ctrl + Shift + P` (Windows)) and type **Export logs**. Select **Codespaces: Export Logs** from the list to download the logs. +1. Open the {% data variables.product.prodname_vscode_command_palette_shortname %} (Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux)) and type **Export logs**. Select **Codespaces: Export Logs** from the list to download the logs. 1. Define where to save the zip archive of logs then click **Save** (desktop) or click **OK** (web). 1. If you are using {% data variables.product.prodname_codespaces %} in the browser, right-click on the zip archive of logs from the Explorer view and select **Download…** to download them to your local machine. @@ -36,7 +36,7 @@ These logs contain detailed information about the codespace, the container, the {% vscode %} -1. Open the {% data variables.product.prodname_vscode %} Command Palette (`Shift + Command + P` (Mac) / `Ctrl + Shift + P` (Windows)) and type **Export logs**. Select **Codespaces: Export Logs** from the list to download the logs. +1. Open the {% data variables.product.prodname_vscode_command_palette_shortname %} (Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux)) and type **Export logs**. Select **Codespaces: Export Logs** from the list to download the logs. 1. Define where to save the zip archive of logs then click **Save** (desktop) or click **OK** (web). {% endvscode %} @@ -55,7 +55,7 @@ These logs contain information about the container, dev container, and their con {% webui %} 1. Connect to the codespace you want to debug. -2. Open the {% data variables.product.prodname_vscode_command_palette %} (`Shift + Command + P` (Mac) / `Ctrl + Shift + P` (Windows)) and type **Creation logs**. Select **Codespaces: View Creation Log** from the list to open the `creation.log` file. +2. Open the {% data variables.product.prodname_vscode_command_palette_shortname %} (Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux)) and type **Creation logs**. Select **Codespaces: View Creation Log** from the list to open the `creation.log` file. If you want to share the log with support, you can copy the text from the creation log into a text editor and save the file locally. @@ -63,7 +63,7 @@ If you want to share the log with support, you can copy the text from the creati {% vscode %} -Open the Command Palette (`Shift + Command + P` (Mac) / `Ctrl + Shift + P` (Windows)) and type **Creation logs**. Select **Codespaces: View Creation Log** from the list to open the `creation.log` file. +Open the {% data variables.product.prodname_vscode_command_palette_shortname %} (Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux)) and type **Creation logs**. Select **Codespaces: View Creation Log** from the list to open the `creation.log` file. If you want to share the log with support, you can copy the text from the creation log into a text editor and save the file locally. diff --git a/content/codespaces/troubleshooting/troubleshooting-your-connection-to-github-codespaces.md b/content/codespaces/troubleshooting/troubleshooting-your-connection-to-github-codespaces.md index d5a3127bb435..94ee61efa034 100644 --- a/content/codespaces/troubleshooting/troubleshooting-your-connection-to-github-codespaces.md +++ b/content/codespaces/troubleshooting/troubleshooting-your-connection-to-github-codespaces.md @@ -18,7 +18,7 @@ redirect_from: Codespaces are set to stop after 30 minutes without any activity. If you try to interact with a codespace after it has stopped, you may see a `503 service unavailable` error. - If a **Start** button is shown in {% data variables.product.prodname_vscode %} or in your browser window, click **Start** to reconnect to the codespace. -- Reset your codespace by reloading the window. From the [command palette](/codespaces/codespaces-reference/using-the-command-palette-in-codespaces#accessing-the-command-palette) in {% data variables.product.prodname_vscode %}, click **Developer: Reload Window**. +- Reset your codespace by reloading the window. From the [Command Palette](/codespaces/codespaces-reference/using-the-command-palette-in-codespaces#accessing-the-command-palette) in {% data variables.product.prodname_vscode %}, click **Developer: Reload Window**. ## Browser cannot connect diff --git a/data/reusables/codespaces/rebuild-command.md b/data/reusables/codespaces/rebuild-command.md index 09f44e08b175..5247bdfa0f0d 100644 --- a/data/reusables/codespaces/rebuild-command.md +++ b/data/reusables/codespaces/rebuild-command.md @@ -1,5 +1,3 @@ -1. Access the {% data variables.product.prodname_vscode_command_palette %} (Shift + Command + P / Ctrl + Shift + P), then start typing "rebuild". Select **Codespaces: Rebuild Container**. +1. Access the {% data variables.product.prodname_vscode_command_palette_shortname %} (Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux)), then start typing "rebuild". Select **Codespaces: Rebuild Container**. ![Rebuild container option](/assets/images/help/codespaces/codespaces-rebuild.png) - - diff --git a/data/reusables/codespaces/remote-explorer.md b/data/reusables/codespaces/remote-explorer.md index c46ed9b53925..545bdcf0c91d 100644 --- a/data/reusables/codespaces/remote-explorer.md +++ b/data/reusables/codespaces/remote-explorer.md @@ -2,7 +2,7 @@ **Note**: If the Remote Explorer is not displayed in the Activity Bar: -1. Access the command palette. For example, by pressing Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux). +1. Access the Command Palette. For example, by pressing Shift+Command+P (Mac) / Ctrl+Shift+P (Windows/Linux). 1. Type: `codespaces`. 1. Click **Codespaces: Details**. diff --git a/script/rendered-content-link-checker.js b/script/rendered-content-link-checker.js index af0e69f2ca1d..5bf9127978c1 100755 --- a/script/rendered-content-link-checker.js +++ b/script/rendered-content-link-checker.js @@ -12,7 +12,7 @@ import path from 'path' import cheerio from 'cheerio' import { program, Option, InvalidArgumentError } from 'commander' import chalk from 'chalk' -import got from 'got' +import got, { RequestError } from 'got' import shortVersions from '../middleware/contextualizers/short-versions.js' import contextualize from '../middleware/context.js' @@ -74,6 +74,9 @@ program .option('-v, --verbose', 'Verbose outputs') .option('--debug', "Loud about everything it's doing") .option('--random', 'Load pages in a random order (useful for debugging)') + .option('--patient', 'Give external link checking longer timeouts and more retries') + .option('-o, --out ', 'Put warnings and errors into a file instead of stdout') + .option('--json-output', 'Print JSON to stdout or file instead') .option('--max ', 'integer argument (default: none)', (value) => { const parsed = parseInt(value, 10) if (isNaN(parsed)) { @@ -107,7 +110,19 @@ program main(program.opts(), program.args) async function main(opts, files) { - const { random, language, filter, exit, debug, max, verbose, list, checkExternalLinks } = opts + const { + random, + language, + filter, + exit, + debug, + max, + verbose, + list, + checkExternalLinks, + jsonOutput, + out, + } = opts // Note! The reason we're using `warmServer()` in this script, // even though there's no server involved, is because @@ -162,6 +177,9 @@ async function main(opts, files) { ) const processPagesEnd = new Date() const flaws = flawsGroups.flat() + if (jsonOutput) { + jsonPrintFlaws(flaws, opts) + } debug && printGlobalCacheHitRatio() @@ -172,6 +190,9 @@ async function main(opts, files) { console.log(`Took ${getDurationString(processPagesStart, processPagesEnd)}`) summarizeFlaws(flaws) + if (out && flaws.length > 0) { + console.log(`All flaws written to ${chalk.bold(out)}`) + } } if (exit) { @@ -244,7 +265,7 @@ function getPages(pageList, languages, filters, files, max) { } async function processPage(page, pageMap, redirects, opts) { - const { bail, verboseUrl } = opts + const { bail, verboseUrl, jsonOutput, out } = opts const allFlawsEach = await Promise.all( page.permalinks.map((permalink) => processPermalink(permalink, page, pageMap, redirects, opts)) @@ -253,17 +274,23 @@ async function processPage(page, pageMap, redirects, opts) { const allFlaws = allFlawsEach.flat() if (bail && allFlaws.length > 0) { - printFlaws(allFlaws, verboseUrl) + if (jsonOutput) { + jsonPrintFlaws(allFlaws, opts) + } else { + printFlaws(allFlaws, { verboseUrl, out }) + } process.exit(1) } - printFlaws(allFlaws, verboseUrl) + if (!jsonOutput) { + printFlaws(allFlaws, { verboseUrl, out }) + } return allFlaws } async function processPermalink(permalink, page, pageMap, redirects, opts) { - const { level, checkAnchors, checkImages, checkExternalLinks } = opts + const { level, checkAnchors, checkImages, checkExternalLinks, verbose, patient } = opts const html = await renderInnerHTML(page, permalink) const $ = cheerio.load(html) const flaws = [] @@ -291,7 +318,8 @@ async function processPermalink(permalink, page, pageMap, redirects, opts) { redirects, pageMap, checkAnchors, - checkExternalLinks + checkExternalLinks, + { verbose, patient } ) if (flaw) { @@ -347,36 +375,92 @@ async function processPermalink(permalink, page, pageMap, redirects, opts) { return flaws } -function printFlaws(flaws, verboseUrl = null) { +function jsonPrintFlaws(flaws, { verboseUrl = null, out = null } = {}) { + const printableFlaws = {} + for (const { page, permalink, href, text, src, flaw } of flaws) { + const fullPath = prettyFullPath(page.fullPath) + + if (!(fullPath in printableFlaws)) { + printableFlaws[fullPath] = [] + } + if (href) { + printableFlaws[fullPath].push({ + href, + url: verboseUrl ? new URL(permalink.href, verboseUrl).toString() : permalink.href, + text, + flaw, + }) + } else if (src) { + printableFlaws[fullPath].push({ + src, + }) + } + } + const message = JSON.stringify(printableFlaws, undefined, 2) + if (out) { + fs.writeFileSync(out, message + '\n', 'utf-8') + } else { + console.log(message) + } +} + +function printFlaws(flaws, { verboseUrl = null, out = null } = {}) { let previousPage = null let previousPermalink = null + + function fout(msg) { + if (out) { + fs.appendFileSync(out, `${msg}\n`, 'utf-8') + } else { + console.log(msg) + } + } + for (const { page, permalink, href, text, src, flaw } of flaws) { + const fullPath = prettyFullPath(page.fullPath) if (page !== previousPage) { - console.log(`PAGE: ${chalk.bold(prettyFullPath(page.fullPath))}`) + if (out) { + fout(`PAGE: ${fullPath}`) + } else { + console.log(`PAGE: ${chalk.bold(fullPath)}`) + } } previousPage = page if (href) { if (previousPermalink !== permalink.href) { if (verboseUrl) { - console.log(` URL: ${new URL(permalink.href, verboseUrl).toString()}`) + fout(` URL: ${new URL(permalink.href, verboseUrl).toString()}`) } else { - console.log(` PERMALINK: ${permalink.href}`) + fout(` PERMALINK: ${permalink.href}`) } } previousPermalink = permalink.href - console.log(` HREF: ${chalk.bold(href)}`) - console.log(` TEXT: ${text}`) + if (out) { + fout(` HREF: ${href}`) + } else { + console.log(` HREF: ${chalk.bold(href)}`) + } + fout(` TEXT: ${text}`) } else if (src) { - console.log(` IMG SRC: ${chalk.bold(src)}`) + if (out) { + fout(` IMG SRC: ${src}`) + } else { + console.log(` IMG SRC: ${chalk.bold(src)}`) + } } else { throw new Error("Flaw has neither 'href' nor 'src'") } - console.log( - ` FLAW: ${flaw.CRITICAL ? chalk.red(flaw.CRITICAL) : chalk.yellow(flaw.WARNING)}` - ) - console.log('') + + if (out) { + fout(` FLAW: ${flaw.CRITICAL ? flaw.CRITICAL : flaw.WARNING}`) + } else { + console.log( + ` FLAW: ${flaw.CRITICAL ? chalk.red(flaw.CRITICAL) : chalk.yellow(flaw.WARNING)}` + ) + } + fout('') } } @@ -402,7 +486,8 @@ async function checkHrefLink( redirects, pageMap, checkAnchors = false, - checkExternalLinks = false + checkExternalLinks = false, + { verbose = false, patient = false } = {} ) { if (href === '#') { if (checkAnchors) { @@ -456,42 +541,38 @@ async function checkHrefLink( if (linksToSkip(href)) { return } - let failed = false - - try { - failed = await checkExternalURL(href) - } catch (err) { - return { WARNING: `Got error when testing ${href}: ${err.toString()}` } - } - if (failed) { - return { CRITICAL: 'Broken external link ' } + const { ok, ...info } = await checkExternalURL(href, { verbose, patient }) + if (!ok) { + return { CRITICAL: `Broken external link (${JSON.stringify(info)})` } } } } -const externalResponseCache = new Map() -const externalResponseWaiting = new Set() +const _fetchCache = new Map() +async function checkExternalURL(url, { verbose = false, patient = false } = {}) { + if (!url.startsWith('https://')) throw new Error('Invalid URL') + const cleanURL = url.split('#')[0] + if (!_fetchCache.has(cleanURL)) { + _fetchCache.set(cleanURL, innerFetch(cleanURL, { verbose, patient })) + } + return _fetchCache.get(cleanURL) +} const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) -async function checkExternalURL(url) { - if (!url.startsWith('https://')) throw new Error('Invalid URL') +// Global for recording which domains we get rate-limited on. +// For example, if you got rate limited on `something.github.com/foo` +// and now we're asked to fetch for `something.github.com/bar` +// it's good to know to now bother yet. +const _rateLimitedDomains = new Map() - if (externalResponseCache.has(url)) { - const result = externalResponseCache.get(url) - return result - } - if (externalResponseWaiting.has(url)) { - // Because this whole script is based on `Promise.all()` you can't - // guarantee that you first make the list of external URLs distinct, - // so you'll end up with N concurrent threads that both start, - // waiting for the same URL to check. - // If there's one going on, sleep and retry all over. - await sleep(500 + Math.random() * 100) - return await checkExternalURL(url) - } - externalResponseWaiting.add(url) +async function innerFetch(url, config = {}) { + const { verbose, useGET, patient } = config + const { hostname } = new URL(url) + if (_rateLimitedDomains.has(hostname)) { + await sleep(_rateLimitedDomains.get(hostname)) + } // The way `got` does retries: // // sleep = 1000 * Math.pow(2, retry - 1) + Math.random() * 100 @@ -507,20 +588,87 @@ async function checkExternalURL(url) { // So there's no point in trying more attempts than 3 because it would // just timeout on the 10s. (i.e. 1000 + 2000 + 4000 + 8000 > 10,000) const retry = { - limit: 3, + limit: patient ? 5 : 2, } - const timeout = 2000 + const timeout = { request: patient ? 10000 : 2000 } - const r = await got(url, { - throwHttpErrors: false, - retry, - timeout, - }) + const headers = { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36', + } + + const retries = config.retries || 0 + const httpFunction = useGET ? got.get : got.head - const failed = r.statusCode !== 200 - externalResponseCache.set(url, failed) - externalResponseWaiting.delete(url) - return failed + if (verbose) console.log(`External URL ${useGET ? 'GET' : 'HEAD'}: ${url} (retries: ${retries})`) + try { + const r = await httpFunction(url, { + headers, + throwHttpErrors: false, + retry, + timeout, + }) + if (verbose) { + console.log( + `External URL ${useGET ? 'GET' : 'HEAD'} ${url}: ${r.statusCode} (retries: ${retries})` + ) + } + + // If we get rate limited, remember that this hostname is now all + // rate limited. And sleep for the number of seconds that the + // `retry-after` header indicated. + if (r.statusCode === 429) { + let sleepTime = Math.min( + 60_000, + Math.max(10_000, getRetryAfterSleep(r.headers['retry-after'])) + ) + // Sprinkle a little jitter so it doesn't all start again all + // at the same time + sleepTime += Math.random() * 10 * 1000 + // Give it a bit extra when we can be really patient + if (patient) sleepTime += 30 * 1000 + + _rateLimitedDomains.set(hostname, sleepTime + Math.random() * 10 * 1000) + if (verbose) + console.log( + chalk.yellow( + `Rate limited on ${hostname} (${url}). Sleeping for ${(sleepTime / 1000).toFixed(1)}s` + ) + ) + await sleep(sleepTime) + return innerFetch(url, Object.assign({}, config, { retries: retries + 1 })) + } else { + _rateLimitedDomains.delete(hostname) + } + + // Perhaps the server doesn't suppport HEAD requests. + // If so, try again with a regular GET. + if ((r.statusCode === 405 || r.statusCode === 404) && !useGET) { + return innerFetch(url, Object.assign({}, config, { useGET: true })) + } + if (verbose) { + console.log((r.ok ? chalk.green : chalk.red)(`${r.statusCode} on ${url}`)) + } + return { ok: r.ok, statusCode: r.statusCode } + } catch (err) { + if (err instanceof RequestError) { + if (verbose) { + console.log(chalk.yellow(`RequestError (${err.message}) on ${url}`)) + } + return { ok: false, requestError: err.message } + } + throw err + } +} + +// Return number of milliseconds from a `Retry-After` header value +function getRetryAfterSleep(headerValue) { + if (!headerValue) return 0 + let ms = Math.round(parseFloat(headerValue) * 1000) + if (isNaN(ms)) { + ms = Math.max(0, new Date(headerValue) - new Date()) + } + return ms } function checkImageSrc(src, $) {