Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,7 @@ jobs:
ENABLED_LANGUAGES: ${{ matrix.name == 'languages' && 'all' || '' }}
ROOT: ${{ (matrix.name == 'fixtures' || matrix.name == 'article-api' || matrix.name == 'landings' ) && 'src/fixtures/fixtures' || '' }}
TRANSLATIONS_FIXTURE_ROOT: ${{ (matrix.name == 'fixtures' || matrix.name == 'article-api') && 'src/fixtures/fixtures/translations' || '' }}
# Enable debug logging when "Re-run jobs with debug logging" is used in GitHub Actions UI
# This will output additional timing and path information to help diagnose timeout issues
RUNNER_DEBUG: ${{ runner.debug }}
run: npm test -- src/${{ matrix.name }}/tests/
18 changes: 0 additions & 18 deletions content/copilot/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,6 @@ changelog:
introLinks:
overview: /copilot/get-started/what-is-github-copilot
quickstart: /copilot/get-started/quickstart
featuredLinks:
startHere:
- /copilot/get-started/what-is-github-copilot
- '{% ifversion fpt %}/copilot/get-started/quickstart{% endif %}'
- '{% ifversion fpt %}/copilot/tutorials/try-extensions{% endif %}'
- '{% ifversion fpt %}/copilot/concepts/agents/coding-agent{% endif %}'
- '{% ifversion ghec %}/copilot/get-started/choose-enterprise-plan{% endif %}'
- '{% ifversion ghec %}/copilot/how-tos/set-up/set-up-for-enterprise{% endif %}'
- '{% ifversion ghec %}/copilot/tutorials/coding-agent/pilot-coding-agent{% endif %}'
popular:
- /copilot/get-started/features
- '{% ifversion fpt %}/copilot/tutorials/copilot-chat-cookbook{% endif %}'
- '{% ifversion fpt %}/copilot/how-tos/get-code-suggestions/get-ide-code-suggestions{% endif %}'
- '{% ifversion fpt %}/copilot/how-tos/chat-with-copilot/chat-in-ide{% endif %}'
- '{% ifversion fpt %}/copilot/how-tos/use-copilot-for-common-tasks/use-copilot-in-the-cli{% endif %}'
- '{% ifversion ghec %}/copilot/how-tos/manage-and-track-spending/manage-request-allowances{% endif %}'
- '{% ifversion ghec %}/copilot/tutorials/roll-out-at-scale/enable-developers/drive-adoption{% endif %}'
- '{% ifversion ghec %}/copilot/tutorials/roll-out-at-scale/enable-developers/integrate-ai-agents{% endif %}'
layout: discovery-landing
heroImage: /assets/images/banner-images/hero-6
versions:
Expand Down
9 changes: 0 additions & 9 deletions content/enterprise-onboarding/index.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
---
title: Enterprise onboarding
intro: 'Onboard your company to {% data variables.product.prodname_ghe_cloud %} by following our recommended plan. You will set up teams with the access they need, create a policy framework to ensure compliance, and automate processes securely throughout your enterprise.'
featuredLinks:
startHere:
- '/enterprise-onboarding/getting-started-with-your-enterprise'
- '/enterprise-onboarding/adding-users-to-your-enterprise'
- '/enterprise-onboarding/setting-up-organizations-and-teams'
- '/enterprise-onboarding/support-for-your-enterprise'
popular:
- '/enterprise-onboarding/govern-people-and-repositories'
- '/enterprise-onboarding/github-actions-for-your-enterprise'
layout: journey-landing
journeyTracks:
- id: 'getting_started'
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ redirect_from:
- /github/site-policy/github-privacy-statement
- /site-policy/privacy-policies/global-privacy-practices
- /site-policy/privacy-policies/github-privacy-statement
- /site-policy/privacy-policies/github-codespaces-privacy-statement
versions:
fpt: '*'
topics:
Expand Down
1 change: 0 additions & 1 deletion content/site-policy/privacy-policies/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ children:
- /github-general-privacy-statement
- /github-subprocessors
- /github-cookies
- /github-codespaces-privacy-statement
- /github-candidate-privacy-policy
redirect_from:
- /github/site-policy/github-data-protection-addendum
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"generate-code-quality-query-list": "tsx src/codeql-queries/scripts/generate-code-quality-query-list.ts",
"generate-content-linter-docs": "tsx src/content-linter/scripts/generate-docs.ts",
"move-content": "tsx src/content-render/scripts/move-content.ts",
"move-by-content-type": "tsx src/content-render/scripts/move-by-content-type.ts",
"openapi-docs": "tsx src/rest/docs.ts",
"playwright-test": "playwright test --config src/fixtures/playwright.config.ts --project=\"Google Chrome\"",
"lint-report": "tsx src/content-linter/scripts/lint-report.ts",
Expand All @@ -78,7 +79,7 @@
"release-banner": "tsx src/ghes-releases/scripts/release-banner.ts",
"repo-sync": "./src/workflows/local-repo-sync.sh",
"reusables": "tsx src/content-render/scripts/reusables-cli.ts",
"resolve-liquid": "tsx src/content-render/scripts/resolve-liquid.ts",
"liquid-tags": "tsx src/content-render/scripts/liquid-tags.ts",
"rendered-content-link-checker": "tsx src/links/scripts/rendered-content-link-checker.ts",
"rendered-content-link-checker-cli": "tsx src/links/scripts/rendered-content-link-checker-cli.ts",
"rest-dev": "tsx src/rest/scripts/update-files.ts",
Expand Down
10 changes: 9 additions & 1 deletion src/ai-tools/lib/file-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function mergeFrontmatterProperties(filePath: string, newPropertiesYaml:
)
}

if (!parsed.content) {
if (parsed.content === undefined || parsed.content === null) {
throw new Error('Failed to parse content from file')
}

Expand Down Expand Up @@ -133,9 +133,11 @@ export function mergeFrontmatterProperties(filePath: string, newPropertiesYaml:
const formattedValue = typeof value === 'string' ? `'${value.replace(/'/g, "''")}'` : value

// Find the line with this field
let foundField = false
for (let i = 1; i < frontmatterEndIndex; i++) {
const line = lines[i]
if (line.startsWith(`${key}:`)) {
foundField = true
// Simple replacement: keep the field name and spacing, replace the value
const colonIndex = line.indexOf(':')
const leadingSpace = line.substring(colonIndex + 1, colonIndex + 2) // Usually a space
Expand All @@ -150,6 +152,12 @@ export function mergeFrontmatterProperties(filePath: string, newPropertiesYaml:
break
}
}

// If field doesn't exist, add it before the closing ---
if (!foundField && frontmatterEndIndex > 0) {
lines.splice(frontmatterEndIndex, 0, `${key}: ${formattedValue}`)
frontmatterEndIndex++
}
}

return lines.join('\n')
Expand Down
62 changes: 62 additions & 0 deletions src/ai-tools/lib/prompt-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { fileURLToPath } from 'url'
import fs from 'fs'
import yaml from 'js-yaml'
import path from 'path'
import readFrontmatter from '@/frame/lib/read-frontmatter'
import { callModelsApi } from '@/ai-tools/lib/call-models-api'

export interface PromptMessage {
Expand Down Expand Up @@ -52,6 +53,67 @@ export function getRefinementDescriptions(editorTypes: string[]): string {
return editorTypes.join(', ')
}

/**
* Enrich context for intro prompt on index.md files
*/
export function enrichIndexContext(filePath: string, content: string): string {
if (!filePath.endsWith('index.md')) return content

try {
const { data } = readFrontmatter(content)
if (!data) return content

// Extract product name from file path (e.g., content/github-models/ -> "GitHub Models")
const productMatch = filePath.replace(/\\/g, '/').match(/content\/([^/]+)/)
const productName = productMatch
? productMatch[1]
.split('-')
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
.join(' ')
: ''

// Get child article titles
const titles: string[] = []
if (data.children && Array.isArray(data.children)) {
const dir = path.dirname(filePath)
for (const childPath of data.children.slice(0, 20)) {
try {
const childFile = path.join(dir, `${childPath.replace(/^\//, '')}.md`)
const childContent = fs.readFileSync(childFile, 'utf8')
const { data: childData } = readFrontmatter(childContent)
if (childData?.title) titles.push(childData.title)
} catch (error) {
if (process.env.AI_TOOLS_VERBOSE === 'true') {
console.warn('Failed to read or parse child article for intro context:', {
filePath,
childPath,
error,
})
}
}
}
}

// Build context note
const parts: string[] = []
if (productName) parts.push(`Product: ${productName}`)
if (titles.length > 0) parts.push(`Child articles: ${titles.join(', ')}`)

if (parts.length > 0) {
return `\n\n---\nContext for intro generation:\n${parts.join('\n')}\n---\n\n${content}`
}
} catch (error) {
if (process.env.AI_TOOLS_VERBOSE === 'true') {
console.warn('Failed to enrich index context for intro generation:', {
filePath,
error,
})
}
}

return content
}

/**
* Call an editor with the given content and options
*/
Expand Down
38 changes: 38 additions & 0 deletions src/ai-tools/prompts/content-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Your job is to read through GitHub Docs articles that I provide and figure out what content type it _most_ aligns to and add the frontmatter property `contentType` with an appropriate value.

**Available `contentType` values (MUST choose from this exact list):**

- 'get-started' (MANDATORY for files with "quickstart" in the filename; also use for other getting started content)
- 'concepts' (use for files with "about" in the filename; also use for other conceptual content)
- 'how-tos' (use for procedural content AND for subdirectory index.md files that have a `children` array)
- 'rai' (optional - only applies to files with "responsible-use" or "rai" in the filenames)
- 'reference'
- 'tutorials'

There is one additional type, 'landing', which can ONLY be used on top-level product index.md files: 'content/<product>/index.md'

**CRITICAL RULE**: If a file is an index.md with MORE than three directory parts (e.g., 'content/<product>/<subdirectory>/index.md'), it is a subdirectory index and should use 'how-tos', NOT 'landing'. The fact that it has a `children` array does NOT make it a landing page.

For prior art, see the following file sets:

- content/copilot/
- content/actions/
- content/account-and-profile/
- content/integrations/

## Output format

**Important:** Output ONLY the new frontmatter property that should be added to the file. Do not output the entire file content.

```yaml
contentType: [selected option]
```

<!-- IF_WRITE_MODE -->
**CRITICAL**: You are in write mode. Output ONLY the YAML frontmatter properties to update.
- Return just the YAML property in the format above
- Do NOT include analysis, explanations, or formatting
- Do NOT wrap in markdown code blocks or ```yaml
- Do NOT include the analysis format
- Just return the clean YAML properties for merging
<!-- END_WRITE_MODE -->
59 changes: 46 additions & 13 deletions src/ai-tools/prompts/intro.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
You are an expert SEO content optimizer specializing in GitHub documentation.
Your task is to analyze a GitHub Docs content file and generate or optimize
You are an expert SEO content optimizer specializing in GitHub documentation.
Your task is to analyze a GitHub Docs content file and generate or optimize
the intro frontmatter property following Google's meta description best practices.

## Context for index.md files

For index.md files, you will receive additional context about the product and child articles:
- Product name (e.g., "GitHub Models", "GitHub Copilot")
- List of child article titles

Use this context to create specific, product-focused intros rather than generic guidance.

**Examples of good vs generic intros:**
- ❌ "Explore tutorials to build projects and learn new skills with GitHub"
- ❌ "Learn practical guides and step-by-step instructions"
- ✅ "Build AI applications with GitHub Models through hands-on tutorials covering model evaluation and deployment"

## Core Requirements

**Primary constraints (must-haves):**
Expand All @@ -11,6 +24,11 @@ the intro frontmatter property following Google's meta description best practice
* Different approach than title - don't start with same words/phrases
* Lists 2-3 concrete outcomes maximum

**For index.md files:**
* Use the provided product name and child article context to create specific intros
* Identify key themes from child article titles to highlight covered topics
* Make intro specific to the product and topics, not generic guidance

**Secondary optimizations (nice-to-haves):**
* Include relevant keywords naturally
* Version-agnostic ({% data variables.* %} OK, avoid {% ifversion %})
Expand Down Expand Up @@ -46,6 +64,15 @@ the intro frontmatter property following Google's meta description best practice
✅ **Uniqueness**: Different angle from article title
✅ **Simplicity**: No colons, no complex lists, flowing sentences

**Examples for index.md files:**

❌ **Too generic** (ignores provided context):
- Bad: "Explore practical guides and step-by-step instructions to accomplish tasks and solve problems on GitHub"

✅ **Product-specific** (uses provided context):
- Better: "Learn to use GitHub Models for prototyping, evaluate AI models, and scale deployments across your organization"
- Or: "Build AI-powered applications with GitHub Models, from initial testing to enterprise-scale deployment"

## Output format

Use plain text formatting optimized for terminal readability:
Expand All @@ -63,23 +90,23 @@ SEO-friendly alternative: "[Single, concise intro that summarizes the article's
## Character limits by content type

- **Articles**: Maximum 354 characters
- **Categories**: Maximum 362 characters
- **Categories**: Maximum 362 characters
- **Map Topics**: Maximum 362 characters

## Liquid syntax guidelines

**Keep these in intros** (they're acceptable for dynamic content):
- {% data variables.* %} - Product names and variables
- {% data reusables.* %} - Reusable content blocks
**When creating intros from scratch** (no existing intro field):
- Use plain text only - DO NOT use {% data variables.* %} or {% data reusables.* %} syntax
- Write out product names in full (e.g., "GitHub Copilot", "GitHub Actions", "GitHub Docs")
- This prevents hallucinating incorrect variable names

**Avoid these in intros** (version-agnostic content preferred):
- {% ifversion %} blocks - Create intros that work across all supported versions
**When updating existing intros** (intro field already exists):
- Preserve any existing {% data variables.* %} and {% data reusables.* %} references
- You may use the same variable patterns that already appear in the existing intro
- Do not introduce new variable references that weren't in the original

**Common variable meanings** (for analysis purposes):
- {% data variables.product.prodname_github %} = "GitHub"
- {% data variables.product.prodname_ghe_server %} = "GitHub Enterprise Server"
- {% data variables.product.prodname_copilot %} = "GitHub Copilot"
- {% data variables.copilot.copilot_coding_agent %} = "Copilot Coding Agent"
**Always avoid**:
- {% ifversion %} blocks - Create intros that work across all supported versions

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.

Expand All @@ -89,6 +116,12 @@ Focus on creating intros that would make sense to someone discovering this conte

**CRITICAL**: You are in write mode. Output ONLY the YAML frontmatter property to update.

**For index.md files:**
- Use the provided product name and child article context in your intro
- Do NOT write generic intros that could apply to any product
- Make the intro specific to the actual product and covered topics

**Output format:**
- Return just: `intro: "your improved intro text"`
- Do NOT include analysis, scoring, explanations, or formatting
- Do NOT wrap in markdown code blocks or ```yaml
Expand Down
Loading
Loading