diff --git a/.devcontainer/test-custom-devcontainer/Dockerfile b/.devcontainer/test-custom-devcontainer/Dockerfile deleted file mode 100644 index 89633bf993..0000000000 --- a/.devcontainer/test-custom-devcontainer/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.177.0/containers/javascript-node/.devcontainer/base.Dockerfile - -# [Choice] Node.js version: 16, 14, 12 -ARG VARIANT="16-buster" -FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} - -# [Optional] Uncomment this section to install additional OS packages. -# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends - -# [Optional] Uncomment if you want to install an additional version of node using nvm -# ARG EXTRA_NODE_VERSION=10 -# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" - -# [Optional] Uncomment if you want to install more global node modules -# RUN su node -c "npm install -g " - -# Install the GitHub CLI see: -# https://github.com/microsoft/vscode-dev-containers/blob/3d59f9fe37edb68f78874620f33dac5a62ef2b93/script-library/docs/github.md -COPY library-scripts/github-debian.sh /tmp/library-scripts/ -RUN apt-get update && bash /tmp/library-scripts/github-debian.sh diff --git a/.devcontainer/test-custom-devcontainer/devcontainer.json b/.devcontainer/test-custom-devcontainer/devcontainer.json index 67869ed146..e1cc942132 100644 --- a/.devcontainer/test-custom-devcontainer/devcontainer.json +++ b/.devcontainer/test-custom-devcontainer/devcontainer.json @@ -1,34 +1,26 @@ { - "name": "docs.github.com", + "name": "test", - // Set *default* container specific settings.json values on container create. "settings": { - "terminal.integrated.shell.linux": "/bin/bash", - "cSpell.language": ",en" + "terminal.integrated.shell.linux": "/bin/zsh", }, - // Install features. Type 'feature' in the VS Code command palette for a full list. - "features": { - "git-lfs": "latest" - }, - // Visual Studio Code extensions which help authoring for docs.github.com. "extensions": [ "dbaeumer.vscode-eslint", - "sissel.shopify-liquid", - "davidanson.vscode-markdownlint", - "bierner.markdown-preview-github-styles", - "streetsidesoftware.code-spell-checker" + "sissel.shopify-liquid" ], + "hostRequirements": { + "cpus": 8, + "memory": "8gb", + "storage": "32gb" + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. - "forwardPorts": [4000], + "forwardPorts": [5000], // Use 'postCreateCommand' to run commands after the container is created. - //"postCreateCommand": "git lfs pull && npm ci", - "postCreateCommand": "echo This file was created by the postCreateCommand in the custom devcontainer.json > aaa-TEST.txt", - - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "node" + "postCreateCommand": "echo test > aaa-TEST.txt" } diff --git a/.vscode/settings.json b/.vscode/settings.json index 1be4592020..2949e3e7ec 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,5 @@ "**/translations": true }, "workbench.editor.enablePreview": false, - "workbench.editor.enablePreviewFromQuickOpen": false + "workbench.editor.enablePreviewFromQuickOpen": false } diff --git a/assets/images/help/business-accounts/repository-invitation-policy-drop-down.png b/assets/images/help/business-accounts/repository-invitation-policy-drop-down.png index a306599643..e1403f0b48 100644 Binary files a/assets/images/help/business-accounts/repository-invitation-policy-drop-down.png and b/assets/images/help/business-accounts/repository-invitation-policy-drop-down.png differ diff --git a/assets/images/help/graphs/dependency-review-action.png b/assets/images/help/graphs/dependency-review-action.png new file mode 100644 index 0000000000..613155ce94 Binary files /dev/null and b/assets/images/help/graphs/dependency-review-action.png differ diff --git a/assets/images/help/issues/filter-archived-items.png b/assets/images/help/issues/filter-archived-items.png new file mode 100644 index 0000000000..2e53fc8685 Binary files /dev/null and b/assets/images/help/issues/filter-archived-items.png differ diff --git a/assets/images/help/issues/projects-beta-assign-button.png b/assets/images/help/issues/projects-beta-assign-button.png new file mode 100644 index 0000000000..b7b6430af8 Binary files /dev/null and b/assets/images/help/issues/projects-beta-assign-button.png differ diff --git a/assets/images/help/issues/projects-beta-assign-dropdown.png b/assets/images/help/issues/projects-beta-assign-dropdown.png new file mode 100644 index 0000000000..07c54d2c5f Binary files /dev/null and b/assets/images/help/issues/projects-beta-assign-dropdown.png differ diff --git a/assets/images/help/issues/restore-archived-item-button.png b/assets/images/help/issues/restore-archived-item-button.png new file mode 100644 index 0000000000..62daabff8d Binary files /dev/null and b/assets/images/help/issues/restore-archived-item-button.png differ diff --git a/assets/images/help/issues/select-all-checkbox.png b/assets/images/help/issues/select-all-checkbox.png new file mode 100644 index 0000000000..d36429df9e Binary files /dev/null and b/assets/images/help/issues/select-all-checkbox.png differ diff --git a/assets/images/help/issues/select-archived-item.png b/assets/images/help/issues/select-archived-item.png new file mode 100644 index 0000000000..525d33b744 Binary files /dev/null and b/assets/images/help/issues/select-archived-item.png differ diff --git a/assets/images/help/issues/select-issue-checkbox.png b/assets/images/help/issues/select-issue-checkbox.png new file mode 100644 index 0000000000..3d590da67c Binary files /dev/null and b/assets/images/help/issues/select-issue-checkbox.png differ diff --git a/assets/images/help/organizations/org-audit-log-export-git-events.png b/assets/images/help/organizations/org-audit-log-export-git-events.png new file mode 100644 index 0000000000..7f0bdd5f5c Binary files /dev/null and b/assets/images/help/organizations/org-audit-log-export-git-events.png differ diff --git a/assets/images/help/organizations/org-audit-log-export.png b/assets/images/help/organizations/org-audit-log-export.png index 76a24cd779..5b8eb841d1 100644 Binary files a/assets/images/help/organizations/org-audit-log-export.png and b/assets/images/help/organizations/org-audit-log-export.png differ diff --git a/assets/images/help/repository/secret-scanning-dry-run-custom-pattern-select-repo.png b/assets/images/help/repository/secret-scanning-dry-run-custom-pattern-select-repo.png new file mode 100644 index 0000000000..ed9e55489b Binary files /dev/null and b/assets/images/help/repository/secret-scanning-dry-run-custom-pattern-select-repo.png differ diff --git a/codespaces-settings.json b/codespaces-settings.json new file mode 100644 index 0000000000..840c49b326 --- /dev/null +++ b/codespaces-settings.json @@ -0,0 +1 @@ +"isInternal": true diff --git a/components/landing/CodeExamples.tsx b/components/landing/CodeExamples.tsx index 4ecbcac9c4..3a57752561 100644 --- a/components/landing/CodeExamples.tsx +++ b/components/landing/CodeExamples.tsx @@ -22,7 +22,8 @@ export const CodeExamples = () => { const isSearching = !!search let searchResults: typeof productCodeExamples = [] if (isSearching) { - const matchReg = new RegExp(search, 'i') + // The following replace method escapes special characters in regular expression creation. + const matchReg = new RegExp(search.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'), 'i') searchResults = productCodeExamples.filter((example) => { const searchableStr = `${example.tags.join(' ')} ${example.title} ${example.description}` return matchReg.test(searchableStr) diff --git a/components/lib/get-rest-code-samples.ts b/components/lib/get-rest-code-samples.ts new file mode 100644 index 0000000000..a7a72b178b --- /dev/null +++ b/components/lib/get-rest-code-samples.ts @@ -0,0 +1,123 @@ +import { parseTemplate } from 'url-template' +import { stringify } from 'javascript-stringify' + +import type { CodeSample, Operation } from '../rest/types' + +/* + Generates a curl example + + For example: + curl \ + -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + https://{hostname}/api/v3/repos/OWNER/REPO/deployments \ + -d '{"ref":"topic-branch","payload":"{ \"deploy\": \"migrate\" }","description":"Deploy request from hubot"}' +*/ +export function getShellExample(operation: Operation, codeSample: CodeSample) { + // This allows us to display custom media types like application/sarif+json + const defaultAcceptHeader = codeSample?.response?.contentType?.includes('+json') + ? codeSample.response.contentType + : 'application/vnd.github.v3+json' + + const requestPath = codeSample?.request?.parameters + ? parseTemplate(operation.requestPath).expand(codeSample.request.parameters) + : operation.requestPath + + let requestBodyParams = '' + if (codeSample?.request?.bodyParameters) { + requestBodyParams = `-d '${JSON.stringify(codeSample.request.bodyParameters)}'` + + // If the content type is application/x-www-form-urlencoded the format of + // the shell example is --data-urlencode param1=value1 --data-urlencode param2=value2 + // For example, this operation: + // https://docs.github.com/en/enterprise/rest/reference/enterprise-admin#enable-or-disable-maintenance-mode + if (codeSample.request.contentType === 'application/x-www-form-urlencoded') { + requestBodyParams = '' + const paramNames = Object.keys(codeSample.request.bodyParameters) + paramNames.forEach((elem) => { + requestBodyParams = `${requestBodyParams} --data-urlencode ${elem}=${codeSample.request.bodyParameters[elem]}` + }) + } + } + + const args = [ + operation.verb !== 'get' && `-X ${operation.verb.toUpperCase()}`, + `-H "Accept: ${defaultAcceptHeader}"`, + `${operation.serverUrl}${requestPath}`, + requestBodyParams, + ].filter(Boolean) + return `curl \\\n ${args.join(' \\\n ')}` +} + +/* + Generates a GitHub CLI example + + For example: + gh api \ + -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + /repos/OWNER/REPO/deployments \ + -fref,topic-branch=0,payload,{ "deploy": "migrate" }=1,description,Deploy request from hubot=2 +*/ +export function getGHExample(operation: Operation, codeSample: CodeSample) { + const defaultAcceptHeader = codeSample?.response?.contentType?.includes('+json') + ? codeSample.response.contentType + : 'application/vnd.github.v3+json' + const hostname = operation.serverUrl !== 'https://api.github.com' ? '--hostname HOSTNAME' : '' + + const requestPath = codeSample?.request?.parameters + ? parseTemplate(operation.requestPath).expand(codeSample.request.parameters) + : operation.requestPath + + let requestBodyParams = '' + if (codeSample?.request?.bodyParameters) { + const bodyParamValues = Object.values(codeSample.request.bodyParameters) + // GitHub CLI does not support sending Objects and arrays using the -F or + // -f flags. That support may be added in the future. It is possible to + // use gh api --input to take a JSON object from standard input + // constructed by jq and piped to gh api. However, we'll hold off on adding + // that complexity for now. + if (bodyParamValues.some((elem) => typeof elem === 'object')) { + return undefined + } + requestBodyParams = Object.keys(codeSample.request.bodyParameters) + .map((key) => { + if (typeof codeSample.request.bodyParameters[key] === 'string') { + return `-f ${key}='${codeSample.request.bodyParameters[key]}'` + } else { + return `-F ${key}=${codeSample.request.bodyParameters[key]}` + } + }) + .join(' ') + } + const args = [ + operation.verb !== 'get' && `--method ${operation.verb.toUpperCase()}`, + `-H "Accept: ${defaultAcceptHeader}"`, + hostname, + requestPath, + requestBodyParams, + ].filter(Boolean) + return `gh api \\\n ${args.join(' \\\n ')}` +} + +/* + Generates an octokit.js example + + For example: + await octokit.request('POST /repos/{owner}/{repo}/deployments'{ + "owner": "OWNER", + "repo": "REPO", + "ref": "topic-branch", + "payload": "{ \"deploy\": \"migrate\" }", + "description": "Deploy request from hubot" + }) + +*/ +export function getJSExample(operation: Operation, codeSample: CodeSample) { + const parameters = codeSample.request + ? { ...codeSample.request.parameters, ...codeSample.request.bodyParameters } + : {} + return `await octokit.request('${operation.verb.toUpperCase()} ${ + operation.requestPath + }', ${stringify(parameters, null, 2)})` +} diff --git a/components/rest/CodeBlock.tsx b/components/rest/CodeBlock.tsx index 40c9ce137b..709b1941a0 100644 --- a/components/rest/CodeBlock.tsx +++ b/components/rest/CodeBlock.tsx @@ -1,15 +1,13 @@ import cx from 'classnames' import { CheckIcon, CopyIcon } from '@primer/octicons-react' import { Tooltip } from '@primer/react' - import useClipboard from 'components/hooks/useClipboard' - import styles from './CodeBlock.module.scss' +import type { ReactNode } from 'react' type Props = { verb?: string - // Only Code samples should have a copy icon - if there's a headingLang it's a code sample - headingLang?: string + headingLang?: ReactNode | string codeBlock: string highlight?: string } @@ -20,20 +18,12 @@ export function CodeBlock({ verb, headingLang, codeBlock, highlight }: Props) { }) return ( -
+
+ {/* Only Code samples should have a copy icon + If there's a headingLang it's a code sample */} {headingLang && (
- {headingLang === 'JavaScript' ? ( - - {headingLang} ( - - @octokit/core.js - - ) - - ) : ( - `${headingLang}` - )} + {headingLang}