Linkify URLs in Actions workflow logs (#36986)
Detect URLs in Actions log output and render them as clickable links, similar to how GitHub Actions handles this. Pre-existing links from ansi_up's OSC 8 parsing are also kept intact. --------- Signed-off-by: silverwind <me@silverwind.io> Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -2,6 +2,34 @@ export function pathEscapeSegments(s: string): string {
|
||||
return s.split('/').map(encodeURIComponent).join('/');
|
||||
}
|
||||
|
||||
// Match HTML tags (to skip) or URLs (to linkify) in HTML content
|
||||
const urlLinkifyPattern = /(<([-\w]+)[^>]*>)|(<\/([-\w]+)[^>]*>)|(https?:\/\/[^\s<>"'`|(){}[\]]+)/gi;
|
||||
const trailingPunctPattern = /[.,;:!?]+$/;
|
||||
|
||||
// Convert URLs to clickable links in HTML, preserving existing HTML tags
|
||||
export function linkifyURLs(html: string): string {
|
||||
let inAnchor = false;
|
||||
return html.replace(urlLinkifyPattern, (match, _openTagFull, openTag, _closeTagFull, closeTag, url) => {
|
||||
// skip URLs inside existing <a> tags
|
||||
if (openTag === 'a') {
|
||||
inAnchor = true;
|
||||
return match;
|
||||
} else if (closeTag === 'a') {
|
||||
inAnchor = false;
|
||||
return match;
|
||||
}
|
||||
if (inAnchor || !url) {
|
||||
return match;
|
||||
}
|
||||
|
||||
const trailingPunct = url.match(trailingPunctPattern);
|
||||
const cleanUrl = trailingPunct ? url.slice(0, -trailingPunct[0].length) : url;
|
||||
const trailing = trailingPunct ? trailingPunct[0] : '';
|
||||
// safe because regexp only matches valid URLs (no quotes or angle brackets)
|
||||
return `<a href="${cleanUrl}" target="_blank">${cleanUrl}</a>${trailing}`; // eslint-disable-line github/unescaped-html-literal
|
||||
});
|
||||
}
|
||||
|
||||
/** Convert an absolute or relative URL to an absolute URL with the current origin. It only
|
||||
* processes absolute HTTP/HTTPS URLs or relative URLs like '/xxx' or '//host/xxx'. */
|
||||
export function toOriginUrl(urlStr: string) {
|
||||
|
||||
Reference in New Issue
Block a user