diff --git a/.changesets/20250314T194426-pr-62.md b/.changesets/20250314T194426-pr-62.md new file mode 100644 index 0000000..f93880a --- /dev/null +++ b/.changesets/20250314T194426-pr-62.md @@ -0,0 +1,9 @@ +--- +title: 'feat: datetime-scalar' +pr: 62 +author: jasonbahl +type: feat +breaking: false +branch: milestone/custom-scalars +--- +null diff --git a/.changesets/20250314T203923-pr-65.md b/.changesets/20250314T203923-pr-65.md new file mode 100644 index 0000000..bceea84 --- /dev/null +++ b/.changesets/20250314T203923-pr-65.md @@ -0,0 +1,9 @@ +--- +title: 'feat: date scalar' +pr: 65 +author: jasonbahl +type: feat +breaking: false +branch: milestone/custom-scalars +--- +null diff --git a/.github/workflows/generate-changeset.yml b/.github/workflows/generate-changeset.yml index 241876f..8c7ed91 100644 --- a/.github/workflows/generate-changeset.yml +++ b/.github/workflows/generate-changeset.yml @@ -180,8 +180,15 @@ jobs: mkdir -p /tmp/release-notes # Generate release notes from all changesets to a temporary file - # Pass the branch parameter to filter changesets for this branch - npm run release:notes -- --branch="${{ steps.target_branch.outputs.name }}" > /tmp/release-notes/temp_notes_raw.md + # For develop branch, include all changesets (including those from milestone branches) + if [[ "${{ steps.target_branch.outputs.name }}" == "develop" ]]; then + echo "Generating release notes for develop branch (including milestone branch changesets)" + npm run release:notes > /tmp/release-notes/temp_notes_raw.md + else + # For other branches, filter by branch + echo "Generating release notes for ${{ steps.target_branch.outputs.name }} branch" + npm run release:notes -- --branch="${{ steps.target_branch.outputs.name }}" > /tmp/release-notes/temp_notes_raw.md + fi # Remove the "Found X changesets" line and any lines starting with ">" grep -v "^>" /tmp/release-notes/temp_notes_raw.md | sed -n '/^Found/!p' > /tmp/release-notes/temp_notes.md @@ -310,7 +317,7 @@ jobs: if: steps.target_branch.outputs.is_milestone == 'true' && steps.check_milestone_pr.outputs.exists == 'false' run: | # Create a new PR from milestone branch to develop - PR_TITLE="feat: ${{ steps.target_branch.outputs.milestone_name }} 🚀" + PR_TITLE="milestone: ${{ steps.target_branch.outputs.milestone_name }} 🚀" # Create the PR body with proper formatting PR_BODY="## Milestone: ${{ steps.target_branch.outputs.milestone_name }}" diff --git a/automation-tests.php b/automation-tests.php index 0758166..99673b4 100644 --- a/automation-tests.php +++ b/automation-tests.php @@ -20,6 +20,8 @@ // SCALARS: // - Email // - Phone +// - DateTime +// - Date // BREAKING CHANGE -// We're simulating a breaking change with this comment. \ No newline at end of file +// We're simulating a breaking change with this comment. diff --git a/scripts/generate-release-notes.js b/scripts/generate-release-notes.js index 614c5d9..d7c7dcb 100755 --- a/scripts/generate-release-notes.js +++ b/scripts/generate-release-notes.js @@ -125,6 +125,31 @@ async function isFirstTimeContributor(author, repoUrl, token) { } } +// Update the readChangesets function to handle milestone branch changesets +async function readChangesets(options = {}) { + const { branch } = options; + + // Read all changesets + const changesets = await readAllChangesets(); + + // If no branch filter is specified, return all changesets + if (!branch) { + return changesets; + } + + // Special case: if branch is 'develop', include changesets from milestone branches + // This ensures that when milestone branches are merged to develop, their changesets are included + if (branch === 'develop') { + return changesets.filter(changeset => + changeset.branch === branch || + changeset.branch.startsWith('milestone/') + ); + } + + // Otherwise, filter by the specified branch + return changesets.filter(changeset => changeset.branch === branch); +} + // Generate release notes in markdown format async function generateMarkdownReleaseNotes(changesets, repoUrl, token) { // Categorize changesets @@ -134,7 +159,7 @@ async function generateMarkdownReleaseNotes(changesets, repoUrl, token) { const bumpType = determineBumpType(changesets); // Start building the release notes - let notes = `## Release Notes\n\n`; + let notes = ``; // Add breaking changes section if there are any if (categories.breaking.length > 0) { @@ -331,7 +356,7 @@ async function generateReleaseNotes() { const token = getGitHubToken(); // Read all changesets, filtering by branch if specified - const changesets = await readAllChangesets(argv.branch); + const changesets = await readChangesets({ branch: argv.branch }); // Log the number of changesets found console.log(`Found ${changesets.length} changesets${argv.branch ? ` for branch ${argv.branch}` : ''}.`); diff --git a/scripts/utils/changesets.js b/scripts/utils/changesets.js index 61ac185..9fdd14b 100644 --- a/scripts/utils/changesets.js +++ b/scripts/utils/changesets.js @@ -68,40 +68,99 @@ async function readChangeset(filePath) { } /** - * Read all changesets + * Read all changesets from the .changesets directory * - * @returns {Promise} Array of parsed changesets + * @param {Object} options Options for reading changesets + * @param {string} options.branch Branch to filter changesets by + * @returns {Promise} Array of changeset objects */ -async function readAllChangesets(branch = null) { - const dir = getChangesetDir(); +async function readAllChangesets(options = {}) { + const { branch } = options || {}; - try { - const files = await fs.readdir(dir); - const changesets = await Promise.all(files.map(async file => { - const filepath = path.join(dir, file); - const content = await fs.readFile(filepath, 'utf8'); - const { data, content: description } = matter(content); + // Get all changeset files + const changesetDir = path.join(process.cwd(), '.changesets'); + const files = await fs.readdir(changesetDir); + const changesetFiles = files.filter(file => file.endsWith('.md')); + + // Read each changeset file + const changesets = await Promise.all( + changesetFiles.map(async file => { + const filePath = path.join(changesetDir, file); + const content = await fs.readFile(filePath, 'utf8'); - return { - ...data, - description: description.trim(), - file - }; - })); - - if (branch) { + // Parse the changeset content + const changeset = parseChangesetContent(content); + + // Add the filename to the changeset + changeset.filename = file; + + return changeset; + }) + ); + + // If branch is specified, filter changesets by branch + if (branch) { + // Special case for develop branch - include milestone branch changesets + if (branch === 'develop') { return changesets.filter(changeset => - !changeset.branch || changeset.branch === branch + !changeset.branch || // Include changesets without branch info + changeset.branch === branch || + changeset.branch.startsWith('milestone/') ); } - return changesets; - } catch (error) { - if (error.code === 'ENOENT') { - return []; - } - throw error; + // Otherwise, filter by the specified branch + return changesets.filter(changeset => + !changeset.branch || // Include changesets without branch info + changeset.branch === branch + ); } + + return changesets; +} + +/** + * Parse changeset content from a file + * + * @param {string} content The content of the changeset file + * @returns {Object} Parsed changeset object + */ +function parseChangesetContent(content) { + // Use your existing parsing logic here + // This should extract title, PR number, author, type, breaking flag, branch, etc. + // from the changeset content + + // Example implementation (adjust based on your actual changeset format): + const lines = content.split('\n'); + const changeset = { + title: '', + pr: null, + author: '', + type: 'other', + breaking: false, + branch: undefined, + description: '' + }; + + // Parse metadata lines (key: value format) + const metadataLines = lines.filter(line => line.includes(':')); + for (const line of metadataLines) { + const [key, value] = line.split(':', 2).map(part => part.trim()); + if (key === 'title') changeset.title = value; + else if (key === 'pr') changeset.pr = parseInt(value, 10) || null; + else if (key === 'author') changeset.author = value; + else if (key === 'type') changeset.type = value; + else if (key === 'breaking') changeset.breaking = value === 'true'; + else if (key === 'branch') changeset.branch = value; + } + + // Extract description (everything after metadata) + const descriptionStartIndex = metadataLines.length; + if (descriptionStartIndex < lines.length) { + changeset.description = lines.slice(descriptionStartIndex).join('\n').trim(); + } + + return changeset; } /**