Skip to content

Commit

Permalink
fix: revalidator, global-config (#1504)
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity authored Sep 19, 2024
1 parent 1472eaf commit b373c4f
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-docs-bundle-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./github/actions/ete-docs-bundle
- uses: ./.github/actions/ete-docs-bundle
with:
deployment_url: ${{ needs.deploy_app_buildwithfern_com.outputs.deployment_url }}
token: ${{ secrets.VERCEL_TOKEN }}
Expand Down
19 changes: 18 additions & 1 deletion clis/vercel-scripts/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { promoteCommand } from "./commands/promote.js";
import { revalidateAllCommand } from "./commands/revalidate-all.js";
import { writefs } from "./cwd.js";
import { cleanDeploymentId } from "./utils/clean-id.js";
import { getVercelTokenFromGlobalConfig } from "./utils/global-config.js";
import { FernDocsRevalidator } from "./utils/revalidator.js";

void yargs(hideBin(process.argv))
Expand All @@ -16,7 +17,7 @@ void yargs(hideBin(process.argv))
type: "string",
description: "The Vercel API token",
demandOption: true,
default: process.env.VERCEL_TOKEN,
default: process.env.VERCEL_TOKEN ?? getVercelTokenFromGlobalConfig(),
})
.options("teamId", {
type: "string",
Expand Down Expand Up @@ -164,5 +165,21 @@ void yargs(hideBin(process.argv))
process.exit(0);
},
)
.command(
"get-deployment <deploymentId>",
"Get a deployment",
(argv) => argv.positional("deploymentId", { type: "string", demandOption: true }),
async ({ deploymentId, token, teamId }) => {
const deployment = await new VercelClient({ token }).deployments.getDeployment(deploymentId, {
teamId,
withGitRepoInfo: "false",
});

// eslint-disable-next-line no-console
console.log(JSON.stringify(deployment, null, 2));

process.exit(0);
},
)
.showHelpOnFail(false)
.parse();
33 changes: 33 additions & 0 deletions clis/vercel-scripts/src/utils/global-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { readFileSync } from "fs";
import { homedir } from "os";
import { join } from "path";

const DARWIN_AUTH_PATH = "~/Library/Application Support/com.vercel.cli/auth.json";
const LINUX_AUTH_PATH = "~/.local/share/com.vercel.cli/auth.json";

function getAuthJson(): string | undefined {
try {
if (process.platform === "darwin") {
return String(readFileSync(join(homedir(), DARWIN_AUTH_PATH.slice(1))));
} else if (process.platform === "linux") {
return String(readFileSync(join(homedir(), LINUX_AUTH_PATH.slice(1))));
}
} catch (_e) {
// do nothing
}
return undefined;
}

export function getVercelTokenFromGlobalConfig(): string | undefined {
const authJson = getAuthJson();

if (authJson == null) {
return undefined;
}
try {
const auth = JSON.parse(authJson);
return auth.token;
} catch (_e) {
return undefined;
}
}
38 changes: 26 additions & 12 deletions clis/vercel-scripts/src/utils/revalidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class FernDocsRevalidator {
this.teamId = teamId;
}

private async *getProductionDomains(): AsyncGenerator<Vercel.GetProjectDomainsResponseDomainsItem> {
private async *getProductionDomains(): AsyncGenerator<Vercel.GetProjectDomainsResponseDomainsItem, void, unknown> {
let cursor: number | undefined = undefined;
do {
const res = await this.vercel.projects.getProjectDomains(this.project, {
Expand All @@ -26,7 +26,9 @@ export class FernDocsRevalidator {
since: cursor ? cursor + 1 : undefined,
});

yield* res.domains.filter((domain) => !BANNED_DOMAINS.includes(domain.apexName));
for (const domain of res.domains.filter((domain) => !BANNED_DOMAINS.includes(domain.apexName))) {
yield domain;
}
cursor = res.pagination.next;
} while (cursor);
}
Expand Down Expand Up @@ -56,6 +58,7 @@ export class FernDocsRevalidator {
logCommand("Revalidating all docs");

const summary: Record<string, { success: number; failed: number }> = {};
const failedDomains: string[] = [];

for await (const domain of this.getProductionDomains()) {
// eslint-disable-next-line no-console
Expand All @@ -66,17 +69,24 @@ export class FernDocsRevalidator {
environment: `https://${domain.name}`,
});

const revalidationSummary = { success: 0, failed: 0 };
const results = await client.revalidation.revalidateAllV4({ limit: 50 });

for await (const result of results) {
if (!result.success) {
// eslint-disable-next-line no-console
console.warn(`[${domain.name}] Failed to revalidate ${result.url}: ${result.error}`);
revalidationSummary.failed++;
} else {
revalidationSummary.success++;
try {
const results = await client.revalidation.revalidateAllV4({ limit: 100 });

const revalidationSummary = (summary[domain.name] = { success: 0, failed: 0 });
for await (const result of results) {
if (!result.success) {
// eslint-disable-next-line no-console
console.warn(`[${domain.name}] Failed to revalidate ${result.url}: ${result.error}`);
revalidationSummary.failed++;
} else {
revalidationSummary.success++;
}
}
summary[domain.name] = revalidationSummary;
} catch (error) {
// eslint-disable-next-line no-console
console.error(`Failed to revalidate ${domain.name}: ${error}`);
failedDomains.push(domain.name);
}
}

Expand All @@ -86,5 +96,9 @@ export class FernDocsRevalidator {
// eslint-disable-next-line no-console
console.log(`- ${domain}: ${success} successful, ${failed} failed`);
});
failedDomains.forEach((domain) => {
// eslint-disable-next-line no-console
console.error(`- ${domain}: Failed to revalidate`);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ const handler: NextApiHandler = async (
req: NextApiRequest,
res: NextApiResponse<FernDocs.RevalidateAllV3Response>,
): Promise<unknown> => {
// when we call res.revalidate() nextjs uses
// req.headers.host to make the network request
const xFernHost = getXFernHostNode(req, true);
req.headers.host = xFernHost;

const revalidate = new Revalidator(res, xFernHost);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ const handler: NextApiHandler = async (
req: NextApiRequest,
res: NextApiResponse<FernDocs.RevalidateAllV4Response>,
): Promise<unknown> => {
// when we call res.revalidate() nextjs uses
// req.headers.host to make the network request
const xFernHost = getXFernHostNode(req, true);
req.headers.host = xFernHost;

/**
* Limit the number of paths to revalidate to max of 100.
Expand Down Expand Up @@ -74,7 +71,8 @@ const handler: NextApiHandler = async (
const node = FernNavigation.utils.convertLoadDocsForUrlResponse(docs.body);
const slugs = NodeCollector.collect(node).getPageSlugs();
const total = slugs.length;
const batch = slugs.slice(offset, offset + limit);
const start = offset * limit;
const batch = slugs.slice(start, start + limit);

const revalidate = new Revalidator(res, xFernHost);
const results = await revalidate.batch(batch);
Expand Down

0 comments on commit b373c4f

Please sign in to comment.