Skip to content

Update markbind deploy success log message#2852

Open
yihao03 wants to merge 3 commits intoMarkBind:masterfrom
yihao03:feat/update-deploy-log
Open

Update markbind deploy success log message#2852
yihao03 wants to merge 3 commits intoMarkBind:masterfrom
yihao03:feat/update-deploy-log

Conversation

@yihao03
Copy link
Contributor

@yihao03 yihao03 commented Mar 2, 2026

  • Update deploy log message
  • Refactor helper function into util directory
  • Lint and update tests

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:
Addresses #2849.
Now update the log message to point to URL of the GitHub Actions and the deployed site URL

Anything you'd like to highlight/discuss:

Testing instructions:
Deploy a website using markbind and observe the log message.

Proposed commit message: (wrap lines at 72 characters)
Update deploy log message to include GitHub Actions URL and deployed site URL


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

@codecov
Copy link

codecov bot commented Mar 2, 2026

Codecov Report

❌ Patch coverage is 96.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 72.04%. Comparing base (5a90880) to head (ed82c00).

Files with missing lines Patch % Lines
packages/core/src/Site/SiteDeployManager.ts 96.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2852      +/-   ##
==========================================
+ Coverage   71.92%   72.04%   +0.12%     
==========================================
  Files         132      132              
  Lines        7358     7362       +4     
  Branches     1516     1580      +64     
==========================================
+ Hits         5292     5304      +12     
+ Misses       2021     1931      -90     
- Partials       45      127      +82     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates MarkBind’s deploy command output to be less misleading by reporting both the GitHub Actions workflow status URL and the expected deployed site URL, while refactoring the CLI logging into a utility and expanding unit tests around URL construction.

Changes:

  • Extend deploy URL generation to return both GitHub Pages and GitHub Actions URLs.
  • Add a CLI utility to log deploy results in a clearer, less “success-looking” way.
  • Add unit tests for GitHub remote parsing and URL construction helpers.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/core/src/Site/SiteDeployManager.ts Introduces DeployResult and URL parsing/construction helpers; returns both GH Pages + Actions URLs from deployment URL resolution.
packages/core/index.ts Re-exports DeployResult type for CLI consumption.
packages/cli/src/util/deploy.ts Adds logDeployResult helper to centralize deploy logging behavior.
packages/cli/src/cmd/deploy.ts Switches deploy command to use the new logging helper and updated deploy return shape.
packages/core/test/unit/Site/SiteDeployManager.test.ts Adds unit tests for parsing remotes and constructing deploy URLs (including CNAME behavior).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +184 to +193
// https://github.com/<name|org>/<repo>.git (HTTPS)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[parts.length - 2].toLowerCase();
return { name, repoName };
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>.git (SSH)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[0].substring(SSH_PREAMBLE.length);
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseGitHubRemoteUrl derives repoName via substring(0, lastIndexOf('.')), which becomes an empty string when the remote URL does not end with a file extension (e.g. https://github.com/user/repo). It can also truncate repo names containing dots when .git is absent. Consider stripping a trailing .git only when present (otherwise keep the full last path segment) so URL construction remains correct for common remote formats.

Suggested change
// https://github.com/<name|org>/<repo>.git (HTTPS)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[parts.length - 2].toLowerCase();
return { name, repoName };
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>.git (SSH)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[0].substring(SSH_PREAMBLE.length);
// https://github.com/<name|org>/<repo>[.git] (HTTPS)
const repoSegment = parts[parts.length - 1] || '';
const repoName = repoSegment.endsWith('.git')
? repoSegment.substring(0, repoSegment.length - 4)
: repoSegment;
const name = (parts[parts.length - 2] || '').toLowerCase();
if (!name || !repoName) {
return null;
}
return { name, repoName };
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>[.git] (SSH)
const lastPart = parts[parts.length - 1] || '';
const repoName = lastPart.endsWith('.git')
? lastPart.substring(0, lastPart.length - 4)
: lastPart;
const ownerAndHost = parts[0] || '';
const name = ownerAndHost.substring(SSH_PREAMBLE.length).toLowerCase();
if (!name || !repoName) {
return null;
}

Copilot uses AI. Check for mistakes.
Comment on lines +184 to +192
// https://github.com/<name|org>/<repo>.git (HTTPS)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[parts.length - 2].toLowerCase();
return { name, repoName };
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>.git (SSH)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue in the SSH branch: using substring(0, lastIndexOf('.')) can yield an empty repoName for remotes like git@github.com:user/repo (no .git), or truncate dotted repo names. Prefer removing only a trailing .git (if present) and otherwise using the full last segment.

Suggested change
// https://github.com/<name|org>/<repo>.git (HTTPS)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[parts.length - 2].toLowerCase();
return { name, repoName };
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>.git (SSH)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
// https://github.com/<name|org>/<repo>[.git] (HTTPS)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.toLowerCase().endsWith('.git')
? repoNameWithExt.slice(0, -4)
: repoNameWithExt;
const name = parts[parts.length - 2].toLowerCase();
return { name, repoName };
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>[.git] (SSH)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.toLowerCase().endsWith('.git')
? repoNameWithExt.slice(0, -4)
: repoNameWithExt;

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +9
export function logDeployResult(result: DeployResult) {
if (result.ghActionsUrl) {
logger.info(`GitHub Actions deployment initiated. Check status at: ${result.ghActionsUrl}`);
}
if (result.ghPagesUrl) {
logger.info(`The website will be deployed at: ${result.ghPagesUrl}`);
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ghPagesUrl can be a bare domain from CNAME (e.g. custom.domain.com), which is not a URL without a scheme. To match the intent of logging a deployed URL, consider normalizing ghPagesUrl for display (e.g. prefixing https:// when no scheme is present).

Suggested change
export function logDeployResult(result: DeployResult) {
if (result.ghActionsUrl) {
logger.info(`GitHub Actions deployment initiated. Check status at: ${result.ghActionsUrl}`);
}
if (result.ghPagesUrl) {
logger.info(`The website will be deployed at: ${result.ghPagesUrl}`);
function normalizeUrlForDisplay(url: string): string {
// If the URL already has a scheme (e.g. http://, https://), leave it as is.
if (/^[a-zA-Z][\w+.-]*:\/\//.test(url)) {
return url;
}
// Assume HTTPS for bare domains such as those from GitHub Pages CNAME.
return `https://${url}`;
}
export function logDeployResult(result: DeployResult) {
if (result.ghActionsUrl) {
logger.info(`GitHub Actions deployment initiated. Check status at: ${result.ghActionsUrl}`);
}
if (result.ghPagesUrl) {
const ghPagesDisplayUrl = normalizeUrlForDisplay(result.ghPagesUrl);
logger.info(`The website will be deployed at: ${ghPagesDisplayUrl}`);

Copilot uses AI. Check for mistakes.
Comment on lines +199 to +204
/**
* Constructs the GitHub Pages URL from a remote URL.
* Returns a URL in the format: https://<name>.github.io/<repo>
*/
static constructGhPagesUrl(repo: ParsedGitHubRepo): string {
return `https://${repo.name}.github.io/${repo.repoName}`;
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring says “Constructs the GitHub Pages URL from a remote URL”, but this function takes a parsed { name, repoName } object, not a URL. Consider updating the comment to avoid confusion about expected inputs.

Copilot uses AI. Check for mistakes.
Comment on lines +207 to +212
/**
* Constructs the GitHub Actions URL from a remote URL.
* Returns a URL in the format: https://github.com/<name>/<repo>/actions
*/
static constructGhActionsUrl(repo: ParsedGitHubRepo): string {
return `https://github.com/${repo.name}/${repo.repoName}/actions`;
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring says “Constructs the GitHub Actions URL from a remote URL”, but this function takes a parsed { name, repoName } object, not a URL. Consider updating the comment to reflect the actual input type.

Copilot uses AI. Check for mistakes.
Comment on lines +175 to +188
static parseGitHubRemoteUrl(remoteUrl: string): ParsedGitHubRepo | null {
const HTTPS_PREAMBLE = 'https://';
const SSH_PREAMBLE = 'git@github.com:';
const GITHUB_IO_PART = 'github.io';

// https://<name|org name>.github.io/<repo name>/
function constructGhPagesUrl(remoteUrl: string) {
if (!remoteUrl) {
return null;
}
const parts = remoteUrl.split('/');
if (remoteUrl.startsWith(HTTPS_PREAMBLE)) {
// https://github.com/<name|org>/<repo>.git (HTTPS)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[parts.length - 2].toLowerCase();
return `https://${name}.${GITHUB_IO_PART}/${repoName}`;
} else if (remoteUrl.startsWith(SSH_PREAMBLE)) {
// git@github.com:<name|org>/<repo>.git (SSH)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[0].substring(SSH_PREAMBLE.length);
return `https://${name}.${GITHUB_IO_PART}/${repoName}`;
}
if (!remoteUrl) {
return null;
}
const parts = remoteUrl.split('/');
if (remoteUrl.startsWith(HTTPS_PREAMBLE)) {
// https://github.com/<name|org>/<repo>.git (HTTPS)
const repoNameWithExt = parts[parts.length - 1];
const repoName = repoNameWithExt.substring(0, repoNameWithExt.lastIndexOf('.'));
const name = parts[parts.length - 2].toLowerCase();
return { name, repoName };
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseGitHubRemoteUrl treats any https://.../<owner>/<repo> URL as GitHub (it doesn’t verify the host is github.com). Since MarkBind supports deploying to non-GitHub remotes, this can generate a bogus GitHub Actions link (and GH Pages link) for e.g. GitLab/Bitbucket HTTPS remotes. Consider validating the hostname/path (e.g. https://github.com/...) before returning a parsed result.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants