Skip to content

Commit

Permalink
Merge branch 'main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
saritai authored Nov 14, 2022
2 parents b49e4f0 + 9715d92 commit 05b24f8
Show file tree
Hide file tree
Showing 189 changed files with 3,580 additions and 2,513 deletions.
12 changes: 5 additions & 7 deletions .github/workflows/sync-search-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ env:
ELASTICSEARCH_URL: http://localhost:9200

jobs:
lint:
dryRunElasticsearchIndexes:
runs-on: ${{ fromJSON('["ubuntu-latest", "ubuntu-20.04-xl"]')[github.repository == 'github/docs-internal'] }}
if: github.repository == 'github/docs-internal' || github.repository == 'github/docs'
steps:
Expand Down Expand Up @@ -95,10 +95,9 @@ jobs:

run: |
mkdir /tmp/records
npm run sync-search-indices -- \
npm run sync-search-indices -- /tmp/records \
--language en \
--version dotcom \
/tmp/records
--version dotcom
ls -lh /tmp/records
Expand All @@ -108,10 +107,9 @@ jobs:
- name: Index into Elasticsearch
run: |
./script/search/index-elasticsearch.js \
./script/search/index-elasticsearch.js /tmp/records \
--language en \
--version dotcom \
/tmp/records
--version dotcom
- name: Check created indexes and aliases
run: |
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 68 additions & 40 deletions components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,33 @@ import { Link } from 'components/Link'

import styles from './Search.module.scss'

// The search endpoint used prior to using /api/search/legacy was
// just /search, which used middleware/search.js. We are leaving that
// middleware in tact to allow folks that previously used the /search
// endpoint to continue doing so. But, we changed the endpoint used by
// the search input on docs.github.com to use the new /api/search/legacy
// endpoint.
// Eventually, we will deprecate the /search and /api/search/legacy
// endpoints and use the /api/search/v1 endpoint, which has
// a different response JSON format.
const SEARCH_API_ENDPOINT = '/api/search/legacy'

type SearchResult = {
const SEARCH_API_ENDPOINT = '/api/search/v1'

type Hit = {
id: string
url: string
breadcrumbs: string
title: string
content: string
score: number
popularity: number
breadcrumbs: string
highlights: {
title: Array<string>
content: Array<string>
}
score?: number
popularity?: number
es_url?: string
}

// Note, the JSON will contain other keys too, but since we don't use
// them in this component, we don't need to specify them.
type Meta = {
found: {
value: number
}
}

type Data = {
hits: Hit[]
meta: Meta
}

type Props = {
Expand Down Expand Up @@ -73,10 +82,14 @@ export function Search({
language,
version,
query,
// In its current state, can't with confidence know if the user
// initiated a search because of the input debounce or if the
// user has finished typing.
autocomplete: 'true',
})}`
: null

const { data: results, error: searchError } = useSWR<SearchResult[], Error>(
const { data, error: searchError } = useSWR<Data, Error>(
fetchURL,
async (url: string) => {
const response = await fetch(url)
Expand All @@ -102,14 +115,14 @@ export function Search({
}
)

const [previousResults, setPreviousResults] = useState<SearchResult[] | undefined>()
const [previousData, setPreviousData] = useState<Data | undefined>()
useEffect(() => {
if (results) {
setPreviousResults(results)
if (data) {
setPreviousData(data)
} else if (!query) {
setPreviousResults(undefined)
setPreviousData(undefined)
}
}, [results, query])
}, [data, query])

// The `isLoading` boolean will become false every time the useSWR hook
// fires off a new XHR. So it toggles from false/true often.
Expand All @@ -124,7 +137,7 @@ export function Search({
// mean saying "Loading..." is a lie!
// That's why we combine them into a final one. We're basically doing
// this to favor *NOT* saying "Loading...".
const isLoadingRaw = Boolean(query && !results && !searchError)
const isLoadingRaw = Boolean(query && !data && !searchError)
const [isLoadingDebounced] = useDebounce<boolean>(isLoadingRaw, 500)
const isLoading = isLoadingRaw && isLoadingDebounced

Expand Down Expand Up @@ -216,7 +229,7 @@ export function Search({
isHeaderSearch={isHeaderSearch}
isMobileSearch={isMobileSearch}
isLoading={isLoading}
results={previousResults}
results={previousData}
closeSearch={closeSearch}
debug={debug}
query={query}
Expand Down Expand Up @@ -342,7 +355,7 @@ function ShowSearchResults({
isHeaderSearch: boolean
isMobileSearch: boolean
isLoading: boolean
results: SearchResult[] | undefined
results: Data | undefined
closeSearch: () => void
debug: boolean
query: string
Expand Down Expand Up @@ -461,11 +474,33 @@ function ShowSearchResults({
{t('search_results_for')}: {query}
</h1>
<p className="ml-4 mb-4 text-normal f5">
{t('matches_displayed')}: {results.length === 0 ? t('no_results') : results.length}
{results.meta.found.value === 0 ? (
t('no_results')
) : (
<span>
{t('matches_found')}: {results.meta.found.value.toLocaleString()}
</span>
)}
.{' '}
{results.meta.found.value > results.hits.length && (
<span>
{t('matches_displayed')}:{' '}
{results.meta.found.value === 0 ? t('no_results') : results.hits.length}
</span>
)}
</p>

<ActionList variant="full">
{results.map(({ url, breadcrumbs, title, content, score, popularity }, index) => {
{results.hits.map((hit, index) => {
const { url, breadcrumbs, title, highlights, score, popularity } = hit

const contentHTML =
highlights.content && highlights.content.length > 0
? highlights.content.join('<br>')
: ''
const titleHTML =
highlights.title && highlights.title.length > 0 ? highlights.title[0] : title

return (
<ActionList.Item className="width-full" key={url}>
<Link
Expand All @@ -476,8 +511,8 @@ function ShowSearchResults({
type: EventType.searchResult,
search_result_query: Array.isArray(query) ? query[0] : query,
search_result_index: index,
search_result_total: results.length,
search_result_rank: (results.length - index) / results.length,
search_result_total: results.hits.length,
search_result_rank: (results.hits.length - index) / results.hits.length,
search_result_url: url,
})
}}
Expand All @@ -487,31 +522,24 @@ function ShowSearchResults({
className={cx('list-style-none', styles.resultsContainer)}
>
<div className={cx('py-2 px-3')}>
{/* Breadcrumbs in search records don't include the page title. These fields may contain <mark> elements that we need to render */}
<Label size="small" variant="accent">
{breadcrumbs.length === 0
? title.replace(/<\/?[^>]+(>|$)|(\/)/g, '')
: breadcrumbs
.split(' / ')
.slice(0, 1)
.join(' ')
.replace(/<\/?[^>]+(>|$)|(\/)/g, '')}
{breadcrumbs ? breadcrumbs.split(' / ')[0] : title}
</Label>
{debug && (
{debug && score !== undefined && popularity !== undefined && (
<small className="float-right">
score: {score.toFixed(4)} popularity: {popularity.toFixed(4)}
</small>
)}
<h2
className={cx('mt-2 text-normal f3 d-block')}
dangerouslySetInnerHTML={{
__html: title,
__html: titleHTML,
}}
/>
<div
className={cx(styles.searchResultContent, 'mt-1 d-block overflow-hidden')}
style={{ maxHeight: '2.5rem' }}
dangerouslySetInnerHTML={{ __html: content }}
dangerouslySetInnerHTML={{ __html: contentHTML }}
/>
<div
className={'d-block mt-2 opacity-70 text-small'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,35 @@ The custom label is created and assigned to the self-hosted runner. Custom label
1. Click on the assigned label to remove it from your self-hosted runner. {% data reusables.actions.actions-unused-labels %}
{% endif %}

## Using the configuration script to create and assign labels
## Programmatically assign labels

You can use the configuration script on the self-hosted runner to create and assign custom labels. For example, this command assigns a label named `gpu` to the self-hosted runner.
You can programmatically assign labels to a self-hosted runner after the runner is created, or during its initial configuration.

```shell
./config.sh --labels gpu
```
* To programmatically assign labels to an existing self-hosted runner, you must use the REST API. For more information, see the "[Self-hosted runners](/rest/actions/self-hosted-runners)" REST API.
* To programmatically assign labels to a self-hosted runner during the initial runner configuration, you can pass label names to the `config` script using the `labels` parameter.

The label is created if it does not already exist. You can also use this approach to assign the default labels to runners, such as `x64` or `linux`. When default labels are assigned using the configuration script, {% data variables.product.prodname_actions %} accepts them as given and does not validate that the runner is actually using that operating system or architecture.
{% note %}

**Note:** You cannot use the `config` script to assign labels to an existing self-hosted runner.

{% endnote %}

You can use comma separation to assign multiple labels. For example:
For example, this command assigns a label named `gpu` when configuring a new self-hosted runner:

```shell
./config.sh --labels gpu,x64,linux
```
```
./config.sh --url <REPOSITORY_URL> --token <REGISTRATION_TOKEN> --labels gpu
```

{% note %}
The label is created if it does not already exist. You can also use this approach to assign the default labels to runners, such as `x64` or `linux`. When default labels are assigned using the configuration script, {% data variables.product.prodname_actions %} accepts them as given and does not validate that the runner is actually using that operating system or architecture.

** Note:** If you replace an existing runner, then you must reassign any custom labels.
You can use comma separation to assign multiple labels. For example:

{% endnote %}
```
./config.sh --url <REPOSITORY_URL> --token <REGISTRATION_TOKEN> --labels gpu,x64,linux
```

{% note %}

** Note:** If you replace an existing runner, then you must reassign any custom labels.

{% endnote %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: Approving workflow runs from private forks
intro: 'When someone without write access submits a pull request to a private repository, a maintainer may need to approve any workflow runs.'
permissions: 'Maintainers with write access to a repository can approve workflow runs.'
versions:
feature: actions-private-fork-workflow-approvals
shortTitle: Approve private fork runs
---

## About workflow runs from private forks

{% data reusables.actions.private-repository-forks-overview %} For more information, see "[Enforcing a policy for fork pull requests in private repositories](/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#enforcing-a-policy-for-fork-pull-requests-in-private-repositories)."

## Approving workflow runs on a pull request from a private fork

{% data reusables.actions.workflows.approve-workflow-runs %}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,4 @@ Workflow runs that have been awaiting approval for more than 30 days are automat

## Approving workflow runs on a pull request from a public fork

Maintainers with write access to a repository can use the following procedure to review and run workflows on pull requests from contributors that require approval.

{% data reusables.repositories.sidebar-pr %}
{% data reusables.repositories.choose-pr-review %}
{% data reusables.repositories.changed-files %}
1. Inspect the proposed changes in the pull request and ensure that you are comfortable running your workflows on the pull request branch. You should be especially alert to any proposed changes in the `.github/workflows/` directory that affect workflow files.
1. If you are comfortable with running workflows on the pull request branch, return to the {% octicon "comment-discussion" aria-label="The discussion icon" %} **Conversation** tab, and under "Workflow(s) awaiting approval", click **Approve and run**.

![Approve and run workflows](/assets/images/help/pull_requests/actions-approve-and-run-workflows-from-fork.png)
{% data reusables.actions.workflows.approve-workflow-runs %}
1 change: 1 addition & 0 deletions content/actions/managing-workflow-runs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ children:
- /re-running-workflows-and-jobs
- /canceling-a-workflow
- /approving-workflow-runs-from-public-forks
- /approving-workflow-runs-from-private-forks
- /reviewing-deployments
- /disabling-and-enabling-a-workflow
- /skipping-workflow-runs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ topics:

Enterprise owners on {% data variables.product.product_name %} can control the requirements for authentication and access to the enterprise's resources.

You can choose to allow members to create and manage user accounts, or your enterprise can create and manage accounts for members with {% data variables.product.prodname_emus %}. If you allow members to manage their own accounts, you can also configure SAML authentication to both increase security and centralize identity and access for the web applications that your team uses.
{% data reusables.enterprise.ghec-authentication-options %}

After learning more about these options, to determine which method is best for your enterprise, see "[Identifying the best authentication method for your enterprise](#identifying-the-best-authentication-method-for-your-enterprise)."

Expand Down
49 changes: 49 additions & 0 deletions content/admin/overview/best-practices-for-enterprises.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Best practices for enterprises
shortTitle: Best practices
intro: Learn {% data variables.product.company_short %}-recommended practices for your enterprise.
versions:
ghec: '*'
ghes: '*'
ghae: '*'
type: overview
topics:
- Accounts
- Enterprise
- Fundamentals
---

{% ifversion ghec %}
## Identify the best authentication method for your enterprise

{% data reusables.enterprise.ghec-authentication-options %}

For help identifying the authentication method that will best meet your needs, see "[About authentication for your enterprise](/admin/identity-and-access-management/managing-iam-for-your-enterprise/about-authentication-for-your-enterprise)."
{% endif %}

## Use policies

We recommend using policies to enforce business rules and regulatory compliance.

{% data reusables.enterprise.about-policies %} For more information, see "[About enterprise policies](/admin/policies/enforcing-policies-for-your-enterprise/about-enterprise-policies)."

## Minimize the number of organizations

Large enterprises often need multiple organizations, but try to create as few as possible to reflect top-level corporate divisions. A smaller number of organizations encourages innersource practices and allows discussions to involve a wider audience.

Instead, you can manage repository access and security requirements at a more granular level within each organization by using teams. For more information, see "[About teams](/organizations/organizing-members-into-teams/about-teams)."

## Avoid extensive collaboration in user-owned repositories

We recommend collaborating in organization-owned repositories whenever possible and minimizing collaboration in user-owned repositories. Organization-owned repositories have more sophisticated security and administrative features, and they remain accessible even as enterprise membership changes.

## Use human-readable usernames

{% ifversion ghec %}If you control the usernames for enterprise members, use{% else %}Use{% endif %} human-readable usernames, and avoid machine-generated IDs that are difficult for humans to read.

You can manage the display of usernames within your enterprise's private repositories. For more information, see "[Managing the display of member names in your organization](/organizations/managing-organization-settings/managing-the-display-of-member-names-in-your-organization)."

## Further reading

- "[Best practices for repositories](/repositories/creating-and-managing-repositories/best-practices-for-repositories)"
- "[Best practices for organizations](/organizations/collaborating-with-groups-in-organizations/best-practices-for-organizations)"
1 change: 1 addition & 0 deletions content/admin/overview/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ children:
- /about-enterprise-accounts
- /system-overview
- /about-the-github-enterprise-api
- /best-practices-for-enterprises
- /creating-an-enterprise-account
- /accessing-compliance-reports-for-your-enterprise
---
Expand Down
Loading

0 comments on commit 05b24f8

Please sign in to comment.