125 lines · 3.3 KB · Text
RawDownload
#!/usr/bin/env node --redirect-warnings=/dev/null const { execFileSync } = require("child_process");const { GITHUB_ACCESS_TOKEN } = process.env; main(); async function main() {  const startDate = new Date(process.argv[2]);  const today = new Date();   console.log(`Release notes from ${startDate} to ${today}\n`);   const releases = await getReleases(startDate, today);  const previewReleases = releases.filter((release) =>    release.tagName.includes("-pre"),  );   const stableReleases = releases.filter(    (release) => !release.tagName.includes("-pre"),  );   // Filter out all preview release, as all of those changes have made it to the stable release, except for the latest preview release  const aggregatedReleases = stableReleases    .concat(previewReleases[0])    .reverse();   const aggregatedReleaseTitles = aggregatedReleases    .map((release) => release.name)    .join(", ");   console.log();  console.log(`Release titles: ${aggregatedReleaseTitles}`);   console.log("Release notes:");  console.log();   for (const release of aggregatedReleases) {    const publishedDate = release.publishedAt.split("T")[0];    console.log(`${release.name}: ${publishedDate}`);    console.log();    console.log(release.description);    console.log();  }} async function getReleases(startDate, endDate) {  const query = `    query ($owner: String!, $repo: String!, $cursor: String) {      repository(owner: $owner, name: $repo) {        releases(first: 100, orderBy: {field: CREATED_AT, direction: DESC}, after: $cursor) {          nodes {            tagName            name            createdAt            publishedAt            description            url            author {              login            }          }          pageInfo {            hasNextPage            endCursor          }        }      }    }  `;   let allReleases = [];  let hasNextPage = true;  let cursor = null;   while (hasNextPage) {    const response = await fetch("https://api.github.com/graphql", {      method: "POST",      headers: {        Authorization: `Bearer ${GITHUB_ACCESS_TOKEN}`,        "Content-Type": "application/json",      },      body: JSON.stringify({        query,        variables: { owner: "zed-industries", repo: "zed", cursor },      }),    });     if (!response.ok) {      throw new Error(`HTTP error! status: ${response.status}`);    }     const data = await response.json();     if (data.errors) {      throw new Error(`GraphQL error: ${JSON.stringify(data.errors)}`);    }     if (!data.data || !data.data.repository || !data.data.repository.releases) {      throw new Error(`Unexpected response structure: ${JSON.stringify(data)}`);    }     const releases = data.data.repository.releases.nodes;    allReleases = allReleases.concat(releases);     hasNextPage = data.data.repository.releases.pageInfo.hasNextPage;    cursor = data.data.repository.releases.pageInfo.endCursor;     lastReleaseOnPage = releases[releases.length - 1];     if (      releases.length > 0 &&      new Date(lastReleaseOnPage.createdAt) < startDate    ) {      break;    }  }   const filteredReleases = allReleases.filter((release) => {    const releaseDate = new Date(release.createdAt);    return releaseDate >= startDate && releaseDate <= endDate;  });   return filteredReleases;}