Skip to content

Commit 1c180b3

Browse files
authored
repo sync
2 parents 0fe23cb + 99a85ff commit 1c180b3

17 files changed

Lines changed: 271 additions & 77 deletions

File tree

content/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ These labels operate cumulatively, so a self-hosted runner’s labels must match
6464

6565
### Routing precedence for self-hosted runners
6666

67-
If you use both repository-level and organization-level runners, {% data variables.product.prodname_dotcom %} follows an order of precedence when routing jobs to self-hosted runners:
68-
69-
1. The job's `runs-on` labels are processed. {% data variables.product.prodname_dotcom %} then attempts to locate a runner that matches the label requirements:
70-
2. The job is sent to a repository-level runner that matches the job labels. If no repository-level runner is available (either busy, offline, or no matching labels):
71-
3. The job is sent to an organization-level runner that matches the job labels. If no organization-level runner is available, the job request fails with an error.
67+
When routing a job to a self-hosted runner, {% data variables.product.prodname_dotcom %} looks for a runner that matches the job's `runs-on` labels:
68+
69+
1. {% data variables.product.prodname_dotcom %} first searches for a runner at the repository level, then at the organization level{% if currentVersion ver_gt "enterprise-server@2.21" %}, then at the enterprise level{% endif %}.
70+
2. The job is then sent to the first matching runner that is online and idle.
71+
- If all matching online runners are busy, the job will queue at the level with the highest number of matching online runners.
72+
- If all matching runners are offline, the job will queue at the level with the highest number of matching offline runners.
73+
- If there are no matching runners at any level, the job will fail.
74+
- If the job remains queued for more than 24 hours, the job will fail.

content/github/site-policy/guidelines-for-legal-requests-of-user-data.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,14 @@ c/o Corporation Service Company
215215
2710 Gateway Oaks Drive, Suite 150N
216216
Sacramento, CA 95833-3505
217217
```
218+
Under state and federal law, GitHub can seek reimbursement for costs associated with compliance with a valid legal demand, such as a subpoena, court order or search warrant. We only charge to recover some costs, and these reimbursements cover only a portion of the costs we actually incur to comply with legal orders.
219+
220+
While we do not charge in emergency situations or in other exigent circumstances, we seek reimbursement for all other legal requests in accordance with the following schedule, unless otherwise required by law:
221+
222+
- Initial search of up to 25 identifiers: Free
223+
- Production of subscriber information/data for up to 5 accounts: Free
224+
- Production of subscriber information/data for more than 5 accounts: $20 per account
225+
- Secondary searches: $10 per search
218226

219227
Please make your requests as specific and narrow as possible, including the following information:
220228

content/rest/reference/permissions-required-for-github-apps.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,9 @@ _Teams_
842842

843843
- [`GET /repos/:owner/:repo/code-scanning/alerts`](/rest/reference/code-scanning#list-code-scanning-alerts-for-a-repository) (:read)
844844
- [`GET /repos/:owner/:repo/code-scanning/alerts/:alert_id`](/rest/reference/code-scanning#get-a-code-scanning-alert) (:read)
845+
- [`PATCH /repos/:owner/:repo/code-scanning/alerts/:alert_id`](/rest/reference/code-scanning#update-a-code-scanning-alert) (:write)
846+
- [`GET /repos/:owner/:repo/code-scanning/analyses`](/rest/reference/code-scanning#list-recent-code-scanning-analyses-for-a-repository) (:read)
847+
- [`POST /repos/:owner/:repo/code-scanning/sarifs`](/rest/reference/code-scanning#upload-a-sarif-file) (:write)
845848
{% endif %}
846849

847850
{% if currentVersion == "free-pro-team@latest" %}

data/ui.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,6 @@ product_sublanding:
160160
tutorial: Tutorial
161161
how_to: How-to guide
162162
reference: Reference
163+
learning_track_nav:
164+
prevGuide: Previous Guide
165+
nextGuide: Next Guide

includes/article.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ <h2 id="in-this-article" class="f5 mb-2"><a class="link-gray-dark" href="#in-thi
6565
</div>
6666
</div>
6767

68-
<div class="d-block border-top border-gray-light mt-4 markdown-body">
68+
<div class="d-block mt-4 markdown-body">
69+
{% if currentLearningTrack and currentLearningTrack.trackName %}
70+
{% include learning-track-nav %}
71+
{% endif %}
6972
{% include helpfulness %}
7073
{% unless page.hidden %}{% include contribution %}{% endunless %}
7174
</div>

includes/learning-track-nav.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<div class="py-3 px-4 rounded bg-white border-gradient--purple-pink d-flex flex-justify-between learning-track-nav">
2+
{% assign track = currentLearningTrack %}
3+
4+
<span class="d-flex flex-column">
5+
{% if track.prevGuide %}
6+
<span class="f6 text-gray">{% data ui.learning_track_nav.prevGuide %}</span>
7+
<a href="{{track.prevGuide.href}}?learn={{track.trackName}}" class="text-bold text-gray">{{track.prevGuide.title}}</a>
8+
{% endif %}
9+
</span>
10+
11+
<span class="d-flex flex-column flex-items-end">
12+
{% if track.nextGuide %}
13+
<span class="f6 text-gray">{% data ui.learning_track_nav.nextGuide %}</span>
14+
<a href="{{track.nextGuide.href}}?learn={{track.trackName}}" class="text-bold text-gray text-right">{{track.nextGuide.title}}</a>
15+
{% endif %}
16+
</span>
17+
18+
</div>

javascripts/search.js

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@ let $searchResultsContainer
1414
let $searchOverlay
1515
let $searchInput
1616

17+
// This is our default placeholder, but it can be localized with a <meta> tag
1718
let placeholder = 'Search topics, products...'
1819
let version
1920
let language
2021

2122
export default function search () {
23+
// First, only initialize search if the elements are on the page
2224
$searchInputContainer = document.getElementById('search-input-container')
2325
$searchResultsContainer = document.getElementById('search-results-container')
24-
2526
if (!$searchInputContainer || !$searchResultsContainer) return
2627

28+
// This overlay exists so if you click off the search, it closes
2729
$searchOverlay = document.querySelector('.search-overlay-desktop')
2830

2931
// There's an index for every version/language combination
@@ -36,15 +38,25 @@ export default function search () {
3638
placeholder = $placeholderMeta.content
3739
}
3840

41+
// Write the search form into its container
3942
$searchInputContainer.append(tmplSearchInput())
4043
$searchInput = $searchInputContainer.querySelector('input')
4144

42-
searchWithYourKeyboard('#search-input-container input', '.ais-Hits-item')
43-
toggleSearchDisplay()
44-
45+
// Prevent 'enter' from refreshing the page
4546
$searchInputContainer.querySelector('form')
4647
.addEventListener('submit', evt => evt.preventDefault())
48+
49+
// Search when the user finished typing
4750
$searchInput.addEventListener('keyup', debounce(onSearch))
51+
52+
// Adds ability to navigate search results with keyboard (up, down, enter, esc)
53+
searchWithYourKeyboard('#search-input-container input', '.ais-Hits-item')
54+
55+
// If the user already has a query in the URL, parse it and search away
56+
parseExistingSearch()
57+
58+
// If not on home page, decide if search panel should be open
59+
toggleSearchDisplay() // must come after parseExistingSearch
4860
}
4961

5062
// The home page and 404 pages have a standalone search
@@ -64,43 +76,37 @@ function toggleSearchDisplay () {
6476
// If not on homepage...
6577
if (hasStandaloneSearch()) return
6678

67-
const $input = $searchInput
68-
69-
// Open modal if input is clicked
70-
$input.addEventListener('focus', () => {
71-
openSearch()
72-
})
79+
// Open panel if input is clicked
80+
$searchInput.addEventListener('focus', openSearch)
7381

74-
// Close modal if overlay is clicked
82+
// Close panel if overlay is clicked
7583
if ($searchOverlay) {
76-
$searchOverlay.addEventListener('click', () => {
77-
closeSearch()
78-
})
84+
$searchOverlay.addEventListener('click', closeSearch)
7985
}
8086

81-
// Open modal if page loads with query in the params/input
82-
if ($input.value) {
87+
// Open panel if page loads with query in the params/input
88+
if ($searchInput.value) {
8389
openSearch()
8490
}
8591
}
8692

93+
// On most pages, opens the search panel
8794
function openSearch () {
8895
$searchInput.classList.add('js-open')
8996
$searchResultsContainer.classList.add('js-open')
9097
$searchOverlay.classList.add('js-open')
9198
}
9299

100+
// Close panel if not on homepage
93101
function closeSearch () {
94-
// Close modal if not on homepage
95102
if (!hasStandaloneSearch()) {
96103
$searchInput.classList.remove('js-open')
97104
$searchResultsContainer.classList.remove('js-open')
98105
$searchOverlay.classList.remove('js-open')
99106
}
100107

101-
const $hits = $searchResultsContainer.querySelector('.ais-Hits')
102-
if ($hits) $hits.style.display = 'none'
103108
$searchInput.value = ''
109+
onSearch()
104110
}
105111

106112
function deriveLanguageCodeFromPath () {
@@ -122,6 +128,7 @@ function deriveVersionFromPath () {
122128
: versionObject.miscBaseName
123129
}
124130

131+
// Wait for the event to stop triggering for X milliseconds before responding
125132
function debounce (fn, delay = 300) {
126133
let timer
127134
return (...args) => {
@@ -130,34 +137,47 @@ function debounce (fn, delay = 300) {
130137
}
131138
}
132139

133-
async function onSearch (evt) {
134-
const query = evt.target.value
135-
136-
const url = new URL(location.origin)
137-
url.pathname = '/search'
138-
url.search = new URLSearchParams({ query, version, language }).toString()
140+
// When the user finishes typing, update the results
141+
async function onSearch () {
142+
const query = $searchInput.value
139143

140-
const response = await fetch(url, {
141-
method: 'GET',
142-
headers: {
143-
'Content-Type': 'application/json'
144-
}
145-
})
146-
const results = response.ok ? await response.json() : []
144+
// Update the URL with the search parameters in the query string
145+
const pushUrl = new URL(location)
146+
pushUrl.search = query ? new URLSearchParams({ query }) : ''
147+
history.pushState({}, '', pushUrl)
148+
149+
// If there's a query, call the endpoint
150+
// Otherwise, there's no results by default
151+
let results = []
152+
if (query.trim()) {
153+
const endpointUrl = new URL(location.origin)
154+
endpointUrl.pathname = '/search'
155+
endpointUrl.search = new URLSearchParams({ language, version, query })
156+
157+
const response = await fetch(endpointUrl, {
158+
method: 'GET',
159+
headers: {
160+
'Content-Type': 'application/json'
161+
}
162+
})
163+
results = response.ok ? await response.json() : []
164+
}
147165

166+
// Either way, update the display
148167
$searchResultsContainer.querySelectorAll('*').forEach(el => el.remove())
149168
$searchResultsContainer.append(
150169
tmplSearchResults(results)
151170
)
152-
153171
toggleStandaloneSearch()
154172

155173
// Analytics tracking
156-
sendEvent({
157-
type: 'search',
158-
search_query: query
159-
// search_context
160-
})
174+
if (query.trim()) {
175+
sendEvent({
176+
type: 'search',
177+
search_query: query
178+
// search_context
179+
})
180+
}
161181
}
162182

163183
// If on homepage, toggle results container if query is present
@@ -189,6 +209,14 @@ function toggleStandaloneSearch () {
189209
if (queryPresent && $results) $results.style.display = 'block'
190210
}
191211

212+
// If the user shows up with a query in the URL, go ahead and search for it
213+
function parseExistingSearch () {
214+
const params = new URLSearchParams(location.search)
215+
if (!params.has('query')) return
216+
$searchInput.value = params.get('query')
217+
onSearch()
218+
}
219+
192220
/** * Template functions ***/
193221

194222
function tmplSearchInput () {

layouts/product-sublanding.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ <h1 class="my-3 font-mktg">{{ page.shortTitle }}</h1>
2929
<div class="circle bg-white text-blue border border-white d-inline-flex">{% octicon "star-fill" height="24" class="v-align-middle m-2"%}</div>
3030
<h3 class="font-mktg h2-mktg my-4">{{ featuredTrack.title }}</h3>
3131
<div class="lead-mktg text-white f5 my-4">{{ featuredTrack.description }}</div>
32-
<a class="d-inline-block border border-white text-white px-4 py-2 f5 no-underline text-bold" role="button" href="{{ featuredTrack.guides[0].href }}">
32+
<a class="d-inline-block border border-white text-white px-4 py-2 f5 no-underline text-bold" role="button" href="{{ featuredTrack.guides[0].href }}?learn={{ featuredTrack.trackName }}">
3333
<span class="mr-2">{% octicon "arrow-right" height="20" %}</span>
3434
{% data ui.product_sublanding.start_path %}
3535
</a>
3636
</div>
3737
</li>
3838
{% for guide in featuredTrack.guides %}
3939
<li class="px-2 d-flex flex-shrink-0">
40-
<a href="{{ guide.href }}" class="d-inline-block Box p-5 bg-white border-gray no-underline">
40+
<a href="{{ guide.href }}?learn={{ featuredTrack.trackName }}" class="d-inline-block Box p-5 bg-white border-gray no-underline">
4141
<div class="d-flex flex-justify-between flex-items-center">
4242
<div class="circle bg-white text-blue border-gradient--purple-pink d-inline-flex">
4343
<span class="m-2 f2 lh-condensed-ultra text-center text-bold text-gradient--blue-purple" style="width: 24px; height: 24px;">{{ forloop.index }}</span>
@@ -61,7 +61,7 @@ <h2 class="mb-3 font-mktg">{% data ui.product_sublanding.learning_paths %}</h2>
6161
<!-- Learning tracks -->
6262
<div class="d-flex flex-wrap flex-items-start my-5">
6363
{% for track in page.learningTracks offset:1 %}
64-
<div class="my-3 px-0 px-4 col-12 col-md-6">
64+
<div class="my-3 px-0 px-4 col-12 col-md-6 learning-track">
6565
<div class="Box js-show-more-container">
6666
<div class="Box-header bg-gradient--purple-pink py-4 d-flex flex-auto flex-items-start flex-wrap">
6767
<div class="d-flex flex-auto flex-items-start col-8 col-md-12 col-xl-8">
@@ -75,14 +75,14 @@ <h4 class="mb-3 text-white font-mktg h3-mktg ">
7575
<p class="text-white">{{ track.description }}</p>
7676
</div>
7777
</div>
78-
<a class="d-inline-block border border-white text-white px-3 py-2 f5 no-underline text-bold no-wrap" role="button" href="{{ track.guides[0].href }}">
78+
<a class="d-inline-block border border-white text-white px-3 py-2 f5 no-underline text-bold no-wrap" role="button" href="{{ track.guides[0].href }}?learn={{ track.trackName }}">
7979
{% data ui.product_sublanding.start %}
8080
<span class="ml-2">{% octicon "arrow-right" height="20" %}</span>
8181
</a>
8282
</div>
8383
<div>
8484
{% for guide in track.guides %}
85-
<a class="Box-row d-flex flex-items-center text-gray-dark no-underline js-show-more-item {% if forloop.index > 4 %}d-none{% endif %}" href="{{ guide.href }}">
85+
<a class="Box-row d-flex flex-items-center text-gray-dark no-underline js-show-more-item {% if forloop.index > 4 %}d-none{% endif %}" href="{{ guide.href }}?learn={{ track.trackName }}">
8686
<div class="circle bg-gray d-inline-flex mr-4">
8787
<span class="m-2 f3 lh-condensed-ultra text-center text-bold text-gradient--purple-pink" style="min-width: 20px; height: 20px;">{{ forloop.index }}</span>
8888
</div>

lib/get-link-data.js

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,45 @@ const removeFPTFromPath = require('./remove-fpt-from-path')
55

66
// rawLinks is an array of paths: [ '/foo' ]
77
// we need to convert it to an array of localized objects: [ { href: '/en/foo', title: 'Foo', intro: 'Description here' } ]
8-
module.exports = async (rawLinks, context) => {
8+
module.exports = async (rawLinks, context, option = { title: true, intro: true }) => {
99
if (!rawLinks) return
1010

11+
if (typeof rawLinks === 'string') {
12+
return await processLink(rawLinks, context, option)
13+
}
14+
1115
const links = []
1216

1317
for (const link of rawLinks) {
14-
const linkPath = link.href || link
15-
const version = context.currentVersion === 'homepage' ? nonEnterpriseDefaultVersion : context.currentVersion
16-
const href = removeFPTFromPath(path.join('/', context.currentLanguage, version, linkPath))
18+
const linkObj = await processLink(link, context, option)
19+
if (!linkObj) {
20+
continue
21+
} else {
22+
links.push(linkObj)
23+
}
24+
}
25+
26+
return links
27+
}
28+
29+
const processLink = async (link, context, option) => {
30+
const linkPath = link.href || link
31+
const version = context.currentVersion === 'homepage' ? nonEnterpriseDefaultVersion : context.currentVersion
32+
const href = removeFPTFromPath(path.join('/', context.currentLanguage, version, linkPath))
33+
34+
const linkedPage = findPage(href, context.pages, context.redirects)
35+
if (!linkedPage) return null
1736

18-
const linkedPage = findPage(href, context.pages, context.redirects)
19-
if (!linkedPage) continue
37+
const opts = { textOnly: true, encodeEntities: true }
2038

21-
const opts = { textOnly: true, encodeEntities: true }
39+
const result = { href, page: linkedPage }
2240

23-
links.push({
24-
href,
25-
title: await linkedPage.renderTitle(context, opts),
26-
intro: await linkedPage.renderProp('intro', context, opts),
27-
page: linkedPage
28-
})
41+
if (option.title) {
42+
result.title = await linkedPage.renderTitle(context, opts)
2943
}
3044

31-
return links
45+
if (option.intro) {
46+
result.intro = await linkedPage.renderProp('intro', context, opts)
47+
}
48+
return result
3249
}

lib/page.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ class Page {
208208
const track = context.site.data['learning-tracks'][context.currentProduct][trackName]
209209
if (!track) continue
210210
learningTracks.push({
211+
trackName,
211212
title: await renderContent(track.title, context, { textOnly: true, encodeEntities: true }),
212213
description: await renderContent(track.description, context, { textOnly: true, encodeEntities: true }),
213214
guides: await getLinkData(track.guides, context)

0 commit comments

Comments
 (0)