diff --git a/CHANGELOG.md b/CHANGELOG.md index b4c8dbe..8f9391a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Features + +- Updater - Add `changelog-path` input for dependencies whose changelog isn't in the repository root, e.g. a package in a monorepo. The commit-based fallback then only lists commits in that directory. ([#183](https://github.com/getsentry/github-workflows/pull/183)) + ### Fixes - Validate PR - Skip PRs opened by bots of GitHub Apps owned by Sentry (the `getsentry` organization or the `sentry` enterprise), such as `sentry-junior[bot]`. App bot users are never repo collaborators, so the write-access check couldn't recognize them. ([#179](https://github.com/getsentry/github-workflows/pull/179)) diff --git a/updater/README.md b/updater/README.md index 3d09e18..6348e06 100644 --- a/updater/README.md +++ b/updater/README.md @@ -171,6 +171,11 @@ Git lookup or fetch failures are also reported as errors. Annotated release tags * type: string * required: false * default: Dependencies +* `changelog-path`: Path of the changelog in the dependency repository, e.g. `packages/cli/CHANGELOG.md` for a package in a monorepo. + Used for the PR description and the changelog entry link. If the changelog isn't found, the commit-based fallback only lists commits in the changelog's directory. + * type: string + * required: false + * default: '' (a changelog in the repository root) * `pr-strategy`: How to handle PRs. Can be either of the following: * `create` - create a new PR for new dependency versions as they are released - maintainers may merge or close older PRs manually diff --git a/updater/action.yml b/updater/action.yml index 5a53486..0c30765 100644 --- a/updater/action.yml +++ b/updater/action.yml @@ -25,6 +25,10 @@ inputs: description: 'Section header to attach the changelog entry to.' required: false default: 'Dependencies' + changelog-path: + description: 'Path of the changelog in the dependency repository, e.g. "packages/cli/CHANGELOG.md" for a package in a monorepo. Defaults to a changelog in the repository root.' + required: false + default: '' pr-strategy: description: 'How to handle PRs - can be either "create" (create new PRs for each version) or "update" (keep single PR updated with latest version)' required: false @@ -361,11 +365,13 @@ runs: TARGET_REPO_URL: ${{ steps.target.outputs.url }} ORIGINAL_TAG: ${{ steps.target.outputs.originalTag }} LATEST_TAG: ${{ steps.target.outputs.latestTag }} + CHANGELOG_PATH: ${{ inputs.changelog-path }} run: | $changelog = ${{ github.action_path }}/scripts/get-changelog.ps1 ` -RepoUrl $env:TARGET_REPO_URL ` -OldTag $env:ORIGINAL_TAG ` - -NewTag $env:LATEST_TAG + -NewTag $env:LATEST_TAG ` + -ChangelogPath "$env:CHANGELOG_PATH" ${{ github.action_path }}/scripts/set-github-env.ps1 TARGET_CHANGELOG $changelog # First we create a PR only if it doesn't exist. We will later overwrite the content with the same action. @@ -450,6 +456,7 @@ runs: LATEST_TAG: ${{ steps.target.outputs.latestTag }} ORIGINAL_VERSION: ${{ steps.target.outputs.originalVersion }} LATEST_VERSION: ${{ steps.target.outputs.latestVersion }} + CHANGELOG_PATH: ${{ inputs.changelog-path }} run: | ${{ github.action_path }}/scripts/update-changelog.ps1 ` -Name $env:DEPENDENCY_NAME ` @@ -460,7 +467,8 @@ runs: -NewTag $env:LATEST_TAG ` -OldVersion $env:ORIGINAL_VERSION ` -NewVersion $env:LATEST_VERSION ` - -Section $env:CHANGELOG_SECTION + -Section $env:CHANGELOG_SECTION ` + -ChangelogPath "$env:CHANGELOG_PATH" - name: Show final git diff if: ${{ ( steps.target.outputs.latestTag != steps.target.outputs.originalTag ) && ( steps.root.outputs.changed == 'false') }} diff --git a/updater/scripts/get-changelog.ps1 b/updater/scripts/get-changelog.ps1 index 39ff8ce..9fc77da 100644 --- a/updater/scripts/get-changelog.ps1 +++ b/updater/scripts/get-changelog.ps1 @@ -1,11 +1,14 @@ param( [Parameter(Mandatory = $true)][string] $RepoUrl, [Parameter(Mandatory = $true)][string] $OldTag, - [Parameter(Mandatory = $true)][string] $NewTag + [Parameter(Mandatory = $true)][string] $NewTag, + # Path of the changelog in the repository, e.g. `packages/cli/CHANGELOG.md`. Defaults to a changelog in the repository root. + [string] $ChangelogPath = '' ) Set-StrictMode -Version latest $PSNativeCommandErrorActionPreference = $false +$ChangelogPath = $ChangelogPath.TrimStart('/') $ErrorActionPreference = 'Stop' $prefix = 'https?://(www\.)?github.com/' @@ -26,7 +29,7 @@ New-Item -ItemType Directory $tmpDir | Out-Null function Get-ChangelogContent { param($ref, $filePath) - $changelogNames = @('CHANGELOG.md', 'changelog.md', 'CHANGELOG.txt', 'changelog.txt', 'CHANGELOG') + $changelogNames = if ($ChangelogPath) { @($ChangelogPath) } else { @('CHANGELOG.md', 'changelog.md', 'CHANGELOG.txt', 'changelog.txt', 'CHANGELOG') } foreach ($name in $changelogNames) { try { @@ -74,7 +77,10 @@ function Get-ChangelogFromCommits { # Get commit messages between tags Write-Host "Getting commits between $oldTag and $newTag..." - $commitMessages = git log "$oldTag..$newTag" --pretty=format:'%s' + # Limit commits to the changelog's directory, e.g. a package in a monorepo + $changelogDir = if ($ChangelogPath) { Split-Path $ChangelogPath -Parent } else { '' } + $pathFilter = if ($changelogDir) { @('--', $changelogDir) } else { @() } + $commitMessages = git log "$oldTag..$newTag" --pretty=format:'%s' @pathFilter if ($LASTEXITCODE -ne 0) { Write-Warning "Could not get commits between $oldTag and $newTag (exit code: $LASTEXITCODE)" return $null diff --git a/updater/scripts/update-changelog.ps1 b/updater/scripts/update-changelog.ps1 index a9864a1..52c0171 100644 --- a/updater/scripts/update-changelog.ps1 +++ b/updater/scripts/update-changelog.ps1 @@ -7,7 +7,9 @@ param( [Parameter(Mandatory = $true)][string] $NewTag, [Parameter(Mandatory = $true)][string] $Section, [string] $OldVersion = '', - [string] $NewVersion = '' + [string] $NewVersion = '', + # Path of the dependency's changelog in its repository, used for the changelog link + [string] $ChangelogPath = '' ) Set-StrictMode -Version latest @@ -149,6 +151,7 @@ $sectionEnd = $i if ("$OldVersion" -eq '') { $OldVersion = GetVersionFromTag $OldTag } if ("$NewVersion" -eq '') { $NewVersion = GetVersionFromTag $NewTag } $tagAnchor = ($NewTag.EndsWith("v$NewVersion") ? "v$NewVersion" : $NewVersion).Replace('.', '') +$changelogFile = if ($ChangelogPath) { $ChangelogPath.TrimStart('/') } else { 'CHANGELOG.md' } $oldTagNice = ($OldVersion -match "^[0-9]") ? "v$OldVersion" : $OldTag $newTagNice = ($NewVersion -match "^[0-9]") ? "v$NewVersion" : $NewTag @@ -187,7 +190,7 @@ if (!$updated) $bulletPoint = $lines | Where-Object { ($_ -match '^ *[-*] ') -and -not ($_ -match '(Bump .* to|\[changelog\]|\[diff\])') } | Select-Object -First 1 $bulletPoint = "$("$bulletPoint".Trim())-"[0] $entry = @("$bulletPoint Bump $Name from $oldTagNice to $newTagNice ($PullRequestMD)", - " $bulletPoint [changelog]($RepoUrl/blob/$MainBranch/CHANGELOG.md#$tagAnchor)", + " $bulletPoint [changelog]($RepoUrl/blob/$MainBranch/$changelogFile#$tagAnchor)", " $bulletPoint [diff]($RepoUrl/compare/$OldTag...$NewTag)") Write-Host "Adding a changelog entry at line $($sectionEnd):" diff --git a/updater/tests/get-changelog.Tests.ps1 b/updater/tests/get-changelog.Tests.ps1 index 86b619e..219b20e 100644 --- a/updater/tests/get-changelog.Tests.ps1 +++ b/updater/tests/get-changelog.Tests.ps1 @@ -401,4 +401,39 @@ Features, fixes and improvements in this release have been contributed by: # Should return empty/null and not crash the script $actual | Should -BeNullOrEmpty } + + It 'with changelog path' { + $actual = & "$PSScriptRoot/../scripts/get-changelog.ps1" ` + -RepoUrl 'https://github.com/getsentry/github-workflows' -OldTag 'v2.0.0' -NewTag 'v2.1.0' -ChangelogPath 'CHANGELOG.md' + $expected = @' +## Changelog + +### 2.1.0 + +#### Features + +- New reusable workflow, `danger.yml`, to check Pull Requests with predefined rules ([#34](https://github-redirect.dependabot.com/getsentry/github-workflows/pull/34)) +'@ + + $actual | Should -Be $expected + } + + It 'git commit fallback only lists commits in the changelog path directory' { + # There's no updater/CHANGELOG.md, so this falls back to commits that touched updater/ + $actual = & "$PSScriptRoot/../scripts/get-changelog.ps1" ` + -RepoUrl 'https://github.com/getsentry/github-workflows' -OldTag 'v2.4.0' -NewTag 'v2.5.0' -ChangelogPath 'updater/CHANGELOG.md' + + $expected = @' +## Changelog + +### Commits between v2.4.0 and v2.5.0 + +- feat: don't update existing branches if there are manually added commits ([#50](https://github-redirect.dependabot.com/getsentry/github-workflows/issues/50)) +- test: improve test scripts & test on all supported platforms ([#49](https://github-redirect.dependabot.com/getsentry/github-workflows/issues/49)) +- chore: use pwsh tee-object to print output as well as set it to GH +- chore: replace deprecated GH set-output +'@ + + $actual | Should -Be $expected + } } diff --git a/updater/tests/update-changelog.Tests.ps1 b/updater/tests/update-changelog.Tests.ps1 index 214220c..c9b2edc 100644 --- a/updater/tests/update-changelog.Tests.ps1 +++ b/updater/tests/update-changelog.Tests.ps1 @@ -49,6 +49,24 @@ Describe 'update-changelog' { Get-Content "$testCasePath/CHANGELOG.md" | Should -Be (Get-Content "$testCasePath/CHANGELOG.md.expected") } + It 'should link to the changelog path' { + $testCasePath = "$TestDrive/changelog-path" + New-Item $testCasePath -ItemType Directory | Out-Null + @('# Changelog', '', '## Unreleased', '', '### Dependencies', '', '- Existing entry', '') | Out-File "$testCasePath/CHANGELOG.md" + + pwsh -WorkingDirectory $testCasePath -File "$PSScriptRoot/../scripts/update-changelog.ps1" ` + -Name 'Dependency' ` + -PR 'https://github.com/getsentry/dependant/pulls/123' ` + -RepoUrl 'https://github.com/getsentry/dependency' ` + -MainBranch 'main' ` + -OldTag '7.16.0' ` + -NewTag '7.17.0' ` + -Section 'Dependencies' ` + -ChangelogPath 'packages/cli/CHANGELOG.md' + + Get-Content "$testCasePath/CHANGELOG.md" | Should -Contain ' - [changelog](https://github.com/getsentry/dependency/blob/main/packages/cli/CHANGELOG.md#7170)' + } + Context 'prefixed tags' { BeforeEach { $testCasePath = "$TestDrive/prefixed-tags"