iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🔢

[Vercel] Displaying the Upstream Repository Version in a Forked Repository

に公開

Implementation Details

Using Vercel and GitHub,
create the "XXX" part of "Build with ○○ ver.XXX".

Overview

Suppose you fork a repository, improve it for your own use, and deploy it using a branch different from main (or master).
Note: Let's call the new branch visual.

The main branch is set up to receive patches from the original repository (upstream), and when incorporated, you merge main into visual (visual ← main) to integrate the latest updates while preserving your own elements.

Then, in the deployment of the visual branch, you display the version information from the original repository's main branch.

This makes it clear that version ○○ of the original system is applied in each specific deployment.

This article covers how to retrieve and display that information.

Environment

  • Next.js: 14.2.10
  • Vercel

Please prepare a Personal Access Token for your own GitHub account.

Implementation

Required Environment Variables

First, from the environment variables per deployment in Vercel:

  • Repository owner of the deployment: VERCEL_GIT_REPO_OWNER
  • Repository name of the deployment: VERCEL_GIT_REPO_SLUG

can be obtained. Vercel provides information regarding commits as environment variables, so let's make use of them.

How to Achieve This

The repository has main and visual branches, and only the information for visual can be obtained from Vercel. Therefore, we will use the GitHub API to retrieve the latest commit of the main branch of that repository. If things go as expected, the same commit should exist in the original repository as well, so all that's left is to create a link based on that information.

Retrieval Part

Determine if the latest commit is included in the upstream repository's commits
const ownerRepoUser = process.env.VERCEL_GIT_REPO_OWNER;
const ownerRepoName = process.env.VERCEL_GIT_REPO_SLUG;
const ownerRepoMainSha =
  ownerRepoUser && ownerRepoName
    ? (
        await fetch(`https://api.github.com/repos/${ownerRepoUser}/${ownerRepoName}/commits?per_page=1`, {
          headers: {
            Authorization: `token ${process.env.GIT_TOKEN!}`,
          },
        }).then((res) => (res.ok ? res.json() : undefined))
      )?.[0]?.sha
    : undefined;
const baseRepoCommitLink = `https://api.github.com/repos/BASE_USER_NAME/BASE_REPO_NAME/commits/${ownerRepoMainSha}`;
const baseRepoCommitIsPresenting = await fetch(baseRepoCommitLink, {
  headers: {
    Authorization: `token ${process.env.GIT_TOKEN!}`,
  },
}).then((res) => res.ok);

ownerRepoMainSha is fetched only if the username and repository name are successfully obtained. Also, when retrieving commit history via the GitHub API, it seems that if you don't specify the number of results (per_page) as a query parameter, it ends up searching with SHA-1 hash value="". In this case, retrieving one is sufficient.
Then, if it is obtained, the SHA-1 hash value is extracted and a similar search is performed in the original repository. No query parameters are needed for this part.

Display Part

{baseRepoCommitIsPresenting ? (
  <Link
    target='_blank'
    rel='noopener noreferrer'
    href={`https://github.com/BASE_USER_NAME/BASE_REPO_NAME/tree/${ownerRepoMainSha}`}
  >
    {String(ownerRepoMainSha).slice(0, 7)}
  </Link>
) : (
  <>Unknown</>
)}

If baseRepoCommitIsPresenting (whether the commit was found in the upstream repository) is true, a tree link is created; otherwise, it displays Unknown, and that's it. Since the display text is originally long, the commonly seen 7-character notation should be sufficient.

GitHubで編集を提案

Discussion