diff --git a/content/repositories/viewing-activity-and-data-for-your-repository/viewing-a-projects-contributors.md b/content/repositories/viewing-activity-and-data-for-your-repository/viewing-a-projects-contributors.md index 5511e1e9ca75..41e5b0330dde 100644 --- a/content/repositories/viewing-activity-and-data-for-your-repository/viewing-a-projects-contributors.md +++ b/content/repositories/viewing-activity-and-data-for-your-repository/viewing-a-projects-contributors.md @@ -23,7 +23,7 @@ category: You can view the top 100 contributors to a repository{% ifversion ghes %}, including commit co-authors,{% endif %} in the contributors graph. Merge commits and empty commits aren't counted as contributions for this graph. {% ifversion fpt or ghec %} -You can also see a list of people who have contributed to the project's Python dependencies. To access this list of community contributors, visit `https://github.com/REPO-OWNER/REPO-NAME/graphs/contributors`. +To access the list of community contributors, visit `https://github.com/REPO-OWNER/REPO-NAME/graphs/contributors`. {% endif %} ## Accessing the contributors graph diff --git a/src/assets/middleware/dynamic-assets.ts b/src/assets/middleware/dynamic-assets.ts index b59d558097e1..4cd1cca5ce80 100644 --- a/src/assets/middleware/dynamic-assets.ts +++ b/src/assets/middleware/dynamic-assets.ts @@ -6,6 +6,9 @@ import sharp from 'sharp' import type { ExtendedRequest } from '@/types' import { assetCacheControl, defaultCacheControl } from '@/frame/middleware/cache-control' import { setFastlySurrogateKey, SURROGATE_ENUMS } from '@/frame/middleware/set-fastly-surrogate-key' +import { createLogger } from '@/observability/logger' + +const logger = createLogger(import.meta.url) /** * This is the indicator that is a virtual part of the URL. @@ -83,6 +86,7 @@ export default async function dynamicAssets( if (req.path.endsWith('.webp')) { const { url, maxWidth, error } = deconstructImageURL(req.path) if (error) { + logger.warn('Invalid dynamic asset URL', { path: req.path, error }) return res.status(400).type('text/plain').send(error.toString()) } try { @@ -149,6 +153,7 @@ export default async function dynamicAssets( 'code' in catchError && (catchError as NodeJS.ErrnoException).code !== 'ENOENT' ) { + logger.error('Failed to process dynamic asset', { path: req.path, error: catchError }) throw catchError } } diff --git a/src/automated-pipelines/lib/update-markdown.ts b/src/automated-pipelines/lib/update-markdown.ts index 6ca36f482b71..49addfc6ee14 100644 --- a/src/automated-pipelines/lib/update-markdown.ts +++ b/src/automated-pipelines/lib/update-markdown.ts @@ -9,8 +9,11 @@ import { difference, isEqual } from 'lodash-es' import { allVersions } from '@/versions/lib/all-versions' import getApplicableVersions from '@/versions/lib/get-applicable-versions' +import { createLogger } from '@/observability/logger' import type { MarkdownFrontmatter } from '@/types' +const logger = createLogger(import.meta.url) + // Type definitions - extending existing type to add missing fields and make most fields optional type FrontmatterData = Partial & { autogenerated?: string @@ -89,6 +92,12 @@ async function removeMarkdownFiles( // If the first array contains items that the second array does not, // it means that a Markdown page was deleted from the OpenAPI schema const filesToRemove = difference(autogeneratedFiles, sourceFiles) + if (filesToRemove.length > 0) { + logger.info('Removing stale markdown files', { + targetDirectory, + count: filesToRemove.length, + }) + } // Markdown files that need to be deleted for (const file of filesToRemove) { unlinkSync(file) @@ -159,6 +168,7 @@ async function updateMarkdownFile( const matcher = new RegExp(commentDelimiter, 'g') const matches = content.match(matcher) if (matches && matches.length > 1) { + logger.error('File has multiple comment delimiters', { file }) throw new Error(`Error: ${file} has multiple comment delimiters`) } @@ -171,9 +181,17 @@ async function updateMarkdownFile( const isVersionsSame = isEqual(sourceData.versions, data.versions) // Only proceed if the content or versions have changed if (isContentSame && isVersionsSame && !isDelimiterMissing) { + logger.debug('Markdown file unchanged, skipping', { file }) return } + logger.debug('Updating existing markdown file', { + file, + contentChanged: !isContentSame, + versionsChanged: !isVersionsSame, + delimiterMissing: isDelimiterMissing, + }) + // Create a new object so that we don't mutate the original data const newData = { ...data } // Only modify the versions property when a file already exists @@ -182,6 +200,7 @@ async function updateMarkdownFile( const newFileContent = appendVersionComment(matter.stringify(targetContent, newData)) await writeFile(file, newFileContent) } else { + logger.info('Creating new markdown file', { file }) await createDirectory(path.dirname(file)) const newFileContent = appendVersionComment( matter.stringify(commentDelimiter + sourceContent, sourceData), @@ -202,6 +221,7 @@ async function updateDirectory( const initialDirectoryListing = await getDirectoryInfo(directory) // If there are no children on disk, remove the directory if (initialDirectoryListing.directoryContents.length === 0 && !rootDirectoryOnly) { + logger.info('Removing empty directory', { directory }) await rimraf(directory) return } @@ -231,6 +251,7 @@ async function updateDirectory( const itemsToAdd = difference(childrenOnDisk, indexChildren) const itemsToRemove = difference(indexChildren, childrenOnDisk) if (itemsToRemove.length === 0 && itemsToAdd.length === 0) { + logger.debug('Index children unchanged, skipping', { indexFile }) return } @@ -268,6 +289,7 @@ function getChildrenToCompare( fmChildren: string[] | undefined, ): ChildrenComparison { if (!fmChildren) { + logger.error('No children property found in index file', { indexFile }) throw new Error(`No children property found in ${indexFile}`) } @@ -386,6 +408,7 @@ async function getIndexFileVersions( files.map(async (file) => { const filepath = path.join(directory, file) if (!existsSync(filepath)) { + logger.error('File does not exist while assembling index versions', { filepath }) throw new Error( `File ${filepath} does not exist while assembling directory index.md files to create parent version.`, ) @@ -396,6 +419,7 @@ async function getIndexFileVersions( } const { data } = matter(await readFile(filepath, 'utf-8')) if (!data || !data.versions) { + logger.error('Frontmatter missing versions', { filepath }) throw new Error(`Frontmatter in ${filepath} does not contain versions.`) } const fmVersions = getApplicableVersions(data.versions) @@ -526,6 +550,7 @@ async function createDirectory(targetDirectory: string): Promise { async function getDirectoryInfo(directory: string): Promise { if (!existsSync(directory)) { + logger.error('Directory does not exist', { directory }) throw new Error(`Directory ${directory} did not exist when attempting to get directory info.`) } const directoryContents = (await readdir(directory)).filter(