Skip to content

Commit 556d092

Browse files
authored
Merge pull request #40934 from github/repo-sync
Repo sync
2 parents 1c6a016 + 61efc29 commit 556d092

File tree

11 files changed

+315
-132
lines changed

11 files changed

+315
-132
lines changed

content/billing/concepts/product-billing/github-actions.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ The following amounts of time for standard runners and artifact storage are incl
5252
> [!NOTE]
5353
> Included minutes cannot be used for larger runners. These runners will always be charged for, even when used by public repositories.
5454
55+
The use of standard {% data variables.product.github %}-hosted runners is free:
56+
57+
* In public repositories
58+
* For {% data variables.product.prodname_pages %}
59+
* For {% data variables.product.prodname_dependabot %}
60+
* For the agentic features ({% data variables.release-phases.public_preview %}) in {% data variables.copilot.copilot_code-review %}
61+
5562
## Using more than your included quota
5663

5764
If your account does not have a valid payment method on file, usage is blocked once you use up your quota.

content/copilot/reference/ai-models/supported-models.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ This table lists the AI models available in {% data variables.product.prodname_c
4747
| {% data variables.copilot.copilot_gpt_5 %} | OpenAI | GA | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
4848
| {% data variables.copilot.copilot_o3 %} | OpenAI | {% data variables.release-phases.closing_down_caps %}: 2025-10-23 | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
4949
| {% data variables.copilot.copilot_o4_mini %} | OpenAI | {% data variables.release-phases.closing_down_caps %}: 2025-10-23 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
50-
| {% data variables.copilot.copilot_claude_haiku_45 %} | Anthropic | {% data variables.release-phases.public_preview_caps %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
50+
| {% data variables.copilot.copilot_claude_haiku_45 %} | Anthropic | GA | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
5151
| {% data variables.copilot.copilot_claude_sonnet_45 %} | Anthropic | GA | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
5252
| {% data variables.copilot.copilot_claude_opus_41 %} | Anthropic | GA | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
5353
| {% data variables.copilot.copilot_claude_opus %} | Anthropic | {% data variables.release-phases.closing_down_caps %}: 2025-10-23 | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
@@ -79,7 +79,7 @@ The following table shows which models are available in each client.
7979
| {% data variables.copilot.copilot_gpt_5 %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
8080
| {% data variables.copilot.copilot_o3 %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
8181
| {% data variables.copilot.copilot_o4_mini %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
82-
| {% data variables.copilot.copilot_claude_haiku_45 %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} |
82+
| {% data variables.copilot.copilot_claude_haiku_45 %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
8383
| {% data variables.copilot.copilot_claude_sonnet_45 %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
8484
| {% data variables.copilot.copilot_claude_opus_41 %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |
8585
| {% data variables.copilot.copilot_claude_opus %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} |

src/ai-tools/prompts/intro.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
You are an expert SEO content optimizer specializing in GitHub documentation.
2+
Your task is to analyze a GitHub Docs content file and generate or optimize
3+
the intro frontmatter property following Google's meta description best practices.
4+
5+
## Your mission
6+
7+
Generate a single, concise intro (one simple sentence maximum - NO colons, NO detailed explanations) that:
8+
9+
* Starts with an action verb (e.g., "Learn," "Discover," "Access," "Explore," "Configure," "Set up," "Build")
10+
* **Uses developer-friendly, direct language** - avoid marketing jargon and corporate buzzwords
11+
* **Prioritizes conciseness over completeness** - cut unnecessary words ruthlessly
12+
* Accurately summarizes the content's core value proposition
13+
* Includes relevant keywords naturally without stuffing
14+
* Follows Google's snippet guidelines (descriptive, informative, compelling)
15+
* Is version-agnostic (no {% ifversion %} blocks, but {% data variables.* %} and {% data reusables.* %} are acceptable)
16+
* Matches the content type (article/category/mapTopic) requirements
17+
* **Goes beyond title restatement** - summarizes the complete article value, not just rephrasing the title
18+
* **Lists concrete steps or outcomes** - what users will actually do or accomplish
19+
* **Limits lists to 2-3 items maximum** - avoid long comma-separated sequences that feel overwhelming
20+
21+
## SEO scoring criteria (1-10 scale)
22+
23+
**10-9 (Excellent)**: Strong action verb, comprehensive content summary, optimal keyword density, clear unique value beyond title, perfect length
24+
**8-7 (Good)**: Action verb present, good content representation, decent keywords, some unique value, appropriate length
25+
**6-5 (Fair)**: Weak action verb or missing, partial content coverage, basic keywords, minimal value beyond title
26+
**4-3 (Poor)**: No action verb, limited content representation, few relevant keywords, mostly restates title
27+
**2-1 (Very Poor)**: Vague or misleading, no clear value proposition, poor keyword usage, completely redundant with title
28+
29+
## Analysis process
30+
31+
1. **Content resolution**: Keep {% data variables.* %} and {% data reusables.* %} but avoid {% ifversion %} blocks
32+
2. **Content analysis**: Identify the article's purpose, target audience, key concepts, and user outcomes
33+
3. **Category detection**: For index pages, analyze child content themes and collective value
34+
35+
4. **SEO optimization**: Use strong action verbs, developer-friendly language, concrete outcomes, and relevant keywords while avoiding corporate buzzwords
36+
37+
**Content Summarization vs. Title Restatement**:
38+
39+
**Avoid title restatement, corporate language, and version-specific Liquid**:
40+
- Title: "Piloting GitHub Copilot coding agent in your organization"
41+
- Poor intro: "Follow best practices to enable {% data variables.copilot.copilot_coding_agent %} in your organization"
42+
- Also poor: "Implement a comprehensive Copilot rollout strategy covering license management, environment setup, training programs, and adoption metrics to drive successful enterprise-wide GitHub Copilot deployment and maximize developer productivity"
43+
44+
**Avoid starting with similar words/phrases as the title**:
45+
- Title: "Learning a new programming language with GitHub Copilot"
46+
- Too similar: "Learn a new programming language with {% data variables.product.prodname_copilot %} by researching syntax..."
47+
- Better: "Use {% data variables.product.prodname_copilot %} chat and code completion to research syntax, practice coding, and master new programming languages faster"
48+
49+
**Use concise, developer-friendly language ({% data variables.* %} OK)**:
50+
- Better intro: "Evaluate use cases, configure security settings, and run pilot trials to successfully deploy {% data variables.copilot.copilot_coding_agent %} in your org"
51+
52+
**Avoid overly long lists and colon constructions**:
53+
- Too long: "Scope issues, pick suitable tasks, iterate via PR comments, add repo instructions, enable MCP tools, and preinstall dependencies"
54+
- Colon problem: "Learn a new programming language with {% data variables.product.prodname_copilot %}: use {% data variables.copilot.copilot_chat_short %} to research syntax and tooling, build and explain small programs with {% data variables.product.prodname_copilot_short %} code completion, and translate familiar code to compare patterns"
55+
- Better: "Scope tasks, configure custom instructions, and iterate on pull requests to improve {% data variables.copilot.copilot_coding_agent %} performance"
56+
- Better: "Use {% data variables.product.prodname_copilot %} features like chat and code completion to research syntax, build programs, and learn new programming languages faster"
57+
58+
**Tone Guidelines**:
59+
- **Developer-friendly**: Use direct, practical language
60+
- **Concise over complete**: Cut words ruthlessly
61+
- **Action-oriented**: List what users will actually do
62+
- **Avoid buzzwords**: Skip marketing language and corporate jargon
63+
- **Use concrete verbs**: Instead of "maximize/optimize/enhance" → use "improve," "boost," "increase," or just describe the outcome directly
64+
- **Limit lists**: Maximum 2-3 items in comma-separated lists - prefer flowing sentences over exhaustive enumerations
65+
- **Avoid colon constructions**: Don't use "Do X: detailed explanation of A, B, and C" format - keep it simple and direct
66+
- **Avoid title similarity**: Don't start with the same words/phrases as the article title - approach the topic from a different angle
67+
68+
The intro should answer: "What specific steps will I take?" rather than "What will this comprehensive solution provide?"
69+
70+
## Analysis Process
71+
72+
1. **First Draft**: Generate an initial improved intro following all guidelines above
73+
2. **Title Check**: Compare your draft to the article title - if it starts with similar words, rewrite with a different approach
74+
3. **Self-Review**: Evaluate your draft against the SEO scoring criteria and tone guidelines
75+
4. **Refinement**: If the draft contains buzzwords, weak verbs, title similarity, or scores below 8/10, create a refined version
76+
77+
## Output format
78+
79+
Use plain text formatting optimized for terminal readability:
80+
81+
```
82+
Title: "[Article title from frontmatter]"
83+
------------------------
84+
85+
Original intro: "[Current intro from the article, or "No intro" if none exists]"
86+
87+
88+
Original SEO score: [X]/10
89+
------------------------
90+
91+
Improved intro: "[Single, concise intro that summarizes the article's full content value, not just restating the title]"
92+
93+
94+
Improved SEO score: [X]/10
95+
------------------------
96+
```
97+
98+
Note: The improved score should reflect your best attempt after internal refinement.
99+
100+
## Character limits by content type
101+
102+
**Priority: Conciseness over character limits**
103+
- Focus on being as concise as possible while maintaining clarity
104+
- Cut every unnecessary word before considering length
105+
- Developer-friendly brevity trumps hitting character targets
106+
107+
**Technical limits** (for reference):
108+
- **Articles**: Maximum 354 characters
109+
- **Categories**: Maximum 362 characters
110+
- **Map Topics**: Maximum 362 characters
111+
112+
## Liquid syntax guidelines
113+
114+
**Keep these in intros** (they're acceptable for dynamic content):
115+
- {% data variables.* %} - Product names and variables
116+
- {% data reusables.* %} - Reusable content blocks
117+
118+
**Avoid these in intros** (version-agnostic content preferred):
119+
- {% ifversion %} blocks - Create intros that work across all supported versions
120+
121+
**Common variable meanings** (for analysis purposes):
122+
- {% data variables.product.prodname_github %} = "GitHub"
123+
- {% data variables.product.prodname_ghe_server %} = "GitHub Enterprise Server"
124+
- {% data variables.product.prodname_copilot %} = "GitHub Copilot"
125+
- {% data variables.copilot.copilot_coding_agent %} = "Copilot Coding Agent"
126+
127+
Focus on creating intros that would make sense to someone discovering this content through Google search, clearly communicating the value and relevance of the article.

src/ai-tools/scripts/ai-tools.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ interface EditorType {
2424

2525
interface EditorTypes {
2626
versioning: EditorType
27+
intro: EditorType
2728
}
2829

2930
const editorTypes: EditorTypes = {
3031
versioning: {
3132
description: 'Refine versioning according to simplification guidance.',
3233
},
34+
intro: {
35+
description: 'Refine intro frontmatter based on SEO and content guidelines.',
36+
},
3337
}
3438

3539
const refinementDescriptions = (): string => {
@@ -88,7 +92,7 @@ program
8892

8993
for (const editorType of editors) {
9094
spinner.text = `Running the AI-powered ${editorType} refinement...`
91-
const answer = await callEditor(editorType, content)
95+
const answer = await callEditor(editorType, content, options.write || false)
9296
spinner.stop()
9397

9498
if (options.write) {
@@ -125,9 +129,20 @@ interface PromptData {
125129
max_tokens?: number
126130
}
127131

128-
async function callEditor(editorType: keyof EditorTypes, content: string): Promise<string> {
132+
async function callEditor(
133+
editorType: keyof EditorTypes,
134+
content: string,
135+
writeMode: boolean,
136+
): Promise<string> {
129137
const markdownPromptPath = path.join(promptDir, `${editorType}.md`)
130-
const markdownPrompt = fs.readFileSync(markdownPromptPath, 'utf8')
138+
let markdownPrompt = fs.readFileSync(markdownPromptPath, 'utf8')
139+
140+
// For intro type in write mode, append special instructions
141+
if (editorType === 'intro' && writeMode) {
142+
markdownPrompt +=
143+
'\n\n**WRITE MODE**: Output only the complete updated file content with the new intro in the frontmatter. Do not include analysis or explanations - just return the file ready to write.'
144+
}
145+
131146
const prompt = yaml.load(fs.readFileSync(promptTemplatePath, 'utf8')) as PromptData
132147

133148
prompt.messages.forEach((msg) => {

src/events/components/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export function sendEvent<T extends EventType>({
122122
screen_width: window.screen.width,
123123
screen_height: window.screen.height,
124124
pixel_ratio: window.devicePixelRatio || 1,
125+
user_agent: navigator.userAgent,
125126

126127
// Location information
127128
timezone: new Date().getTimezoneOffset() / -60,

src/events/lib/schema.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@ const context = {
168168
description: 'The device pixel ratio.',
169169
minimum: 0,
170170
},
171+
ip: {
172+
type: 'string',
173+
description: 'The IP address of the user.',
174+
},
175+
user_agent: {
176+
type: 'string',
177+
description: 'The raw user agent string from the browser.',
178+
},
171179

172180
// Location information
173181
timezone: {

src/events/middleware.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ router.post(
7878
// JSON.stringify removes `undefined` values but not `null`, and we don't want to send `null` to Hydro
7979
body.context.dotcom_user = req.cookies?.dotcom_user ? req.cookies.dotcom_user : undefined
8080
body.context.is_staff = Boolean(req.cookies?.staffonly)
81+
// Add IP address and user agent from request
82+
// Moda forwards the client's IP using the `fastly-client-ip` header
83+
body.context.ip = req.headers['fastly-client-ip'] as string | undefined
84+
body.context.user_agent ??= req.headers['user-agent']
8185
}
8286
const validate = validators[type]
8387
if (!validate(body)) {

src/events/tests/middleware.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ describe('POST /events', () => {
5252
// Location information
5353
timezone: -7,
5454
user_language: 'en-US',
55+
ip: '192.0.2.1',
56+
user_agent:
57+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
5558
},
5659
}
5760

@@ -88,6 +91,9 @@ describe('POST /events', () => {
8891
// Location information
8992
timezone: -7,
9093
user_language: 'en-US',
94+
ip: '192.0.2.1',
95+
user_agent:
96+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
9197
},
9298
}
9399

src/events/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export type EventProps = {
5050
screen_width?: number
5151
screen_height?: number
5252
pixel_ratio?: number
53+
ip?: string
54+
user_agent?: string
5355
timezone: number
5456
user_language: string
5557
os_preference: string

0 commit comments

Comments
 (0)