diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000000..6642e4b7df6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,25 @@ +## Description + + + +Fixes # (issue, if applicable) + +## Checklist + +- [ ] Test cases added +- [ ] Performance benchmarks added in case of performance changes +- [ ] Release notes entry updated: + > Please make sure to add an entry with short succint description of the change as well as link to this pull request to the respective release notes file, if applicable. + > + > Release notes files: + > - If anything under `src/Compiler` has been changed, please make sure to make an entry in `docs/release-notes/FSharp.Compiler.Service/.md`, where `` is usually "highest" one, e.g. `42.8.200` + > - If language feature was added (i.e. `LanguageFeatures.fsi` was changed), please add it to `docs/releae-notes/Language/preview.md` + > - If a change to `FSharp.Core` was made, please make sure to edit `docs/release-notes/FSharp.Core/.md` where version is "highest" one, e.g. `8.0.200`. + + > Examples of release notes entries: + > - Respect line limit in quick info popup - https://github.com/dotnet/fsharp/pull/16208 + > - More inlines for Result module - https://github.com/dotnet/fsharp/pull/16106 + > - Miscellaneous fixes to parens analysis - https://github.com/dotnet/fsharp/pull/16262 + > + + > **If you believe that release notes are not necessary for this PR, please add `NO_RELEASE_NOTES` label to the pull request.** \ No newline at end of file diff --git a/.github/workflows/check_release_notes.yml b/.github/workflows/check_release_notes.yml index 9697e16a330..14b3c85ca51 100644 --- a/.github/workflows/check_release_notes.yml +++ b/.github/workflows/check_release_notes.yml @@ -28,3 +28,260 @@ jobs: repo: context.repo.repo, }); return { "pr_number": context.issue.number, "ref": result.data.head.ref, "repository": result.data.head.repo.full_name}; + - name: Checkout repo + uses: actions/checkout@v2 + with: + repository: ${{ fromJson(steps.get-pr.outputs.result).repository }} + ref: ${{ fromJson(steps.get-pr.outputs.result).ref }} + fetch-depth: 0 + - name: Check for release notes changes + id: release_notes_changes + run: | + set -e + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + FSHARP_REPO_URL="https://github.com/${GITHUB_REPOSITORY}" + PR_AUTHOR="${{ github.event.pull_request.user.login }}" + PR_NUMBER=${{ github.event.number }} + PR_URL="${FSHARP_REPO_URL}/pull/${PR_NUMBER}" + + echo "PR Tags: ${{ toJson(github.event.pull_request.labels) }}" + + OPT_OUT_RELEASE_NOTES=${{ contains(github.event.pull_request.labels.*.name, 'NO_RELEASE_NOTES') }} + + echo "Opt out of release notes: $OPT_OUT_RELEASE_NOTES" + + # Parse version from eng/Versions.props + # For FSarp.Core: + # 8 + # 0 + # 100 + # For FCS: + # FCSMajorVersion>43 + # 8 + # $(FSBuildVersion) + # For VS: + # 17 + # 8 + + _fs_major_version=$(grep -oPm1 "(?<=)[^<]+" eng/Versions.props) + _fs_minor_version=$(grep -oPm1 "(?<=)[^<]+" eng/Versions.props) + _fs_build_version=$(grep -oPm1 "(?<=)[^<]+" eng/Versions.props) + _fcs_major_version=$(grep -oPm1 "(?<=)[^<]+" eng/Versions.props) + _fcs_minor_version=$(grep -oPm1 "(?<=)[^<]+" eng/Versions.props) + _fcs_build_version=$_fs_build_version + _vs_major_version=$(grep -oPm1 "(?<=)[^<]+" eng/Versions.props) + _vs_minor_version=$(grep -oPm1 "(?<=)[^<]+" eng/Versions.props) + + FSHARP_CORE_VERSION="$_fs_major_version.$_fs_minor_version.$_fs_build_version" + FCS_VERSION="$_fcs_major_version.$_fcs_minor_version.$_fcs_build_version" + VISUAL_STUDIO_VERSION="$_vs_major_version.$_vs_minor_version" + + echo "Found F# version: ${FSHARP_CORE_VERSION}" + echo "Found FCS version: ${FCS_VERSION}" + echo "Found Visual Studio version: ${VISUAL_STUDIO_VERSION}" + + [[ "$FSHARP_CORE_VERSION" =~ ^[0-9]+\.[0-9]+.[0-9]+$ ]] || (echo " Invalid FSharp.Core Version parsed"; exit 1) + [[ "$FCS_VERSION" =~ ^[0-9]+\.[0-9]+.[0-9]+$ ]] || (echo " Invalid FCS Version parsed"; exit 1) + [[ "$VISUAL_STUDIO_VERSION" =~ ^[0-9]+\.[0-9]+$ ]] || (echo " Invalid Visual Studio Version parsed"; exit 1) + + _release_notes_base_path='docs/release-notes' + _fsharp_core_release_notes_path="${_release_notes_base_path}/FSharp.Core/${FSHARP_CORE_VERSION}.md" + _fsharp_compiler_release_notes_path="${_release_notes_base_path}/FSharp.Compiler.Service/${FSHARP_CORE_VERSION}.md" + _fsharp_language_release_notes_path="${_release_notes_base_path}/Language/preview.md" + _fsharp_vs_release_notes_path="${_release_notes_base_path}/VisualStudio/${VISUAL_STUDIO_VERSION}.md" + + readonly paths=( + "src/FSharp.Core|${_fsharp_core_release_notes_path}" + "src/Compiler|${_fsharp_compiler_release_notes_path}" + "LanguageFeatures.fsi|${_fsharp_language_release_notes_path}" + "vsintegration/src|${_fsharp_vs_release_notes_path}" + ) + + # Check all changed paths + RELEASE_NOTES_MESSAGE="" + RELEASE_NOTES_MESSAGE_DETAILS="" + RELEASE_NOTES_FOUND="" + RELEASE_NOTES_CHANGES_SUMMARY="" + RELEASE_NOTES_NOT_FOUND="" + PULL_REQUEST_FOUND=true + + gh repo set-default ${GITHUB_REPOSITORY} + + _modified_paths=`gh pr view ${PR_NUMBER} --json files --jq '.files.[].path'` + + for fields in ${paths[@]} + do + IFS=$'|' read -r path release_notes <<< "$fields" + echo "Checking for changed files in: $path" + + # Check if path is in modified files: + if [[ "${_modified_paths[@]}" =~ "${path}" ]]; then + echo " Found $path in modified files" + echo " Checking if release notes modified in: $release_notes" + if [[ "${_modified_paths[@]}" =~ "${release_notes}" ]]; then + echo " Found $release_notes in modified files" + echo " Checking for pull request URL in $release_notes" + + if [[ ! -f $release_notes ]]; then + echo " $release_notes does not exist, please, create it." + #exit 1; + fi + + _pr_link_occurences=`grep -c "${PR_URL}" $release_notes || true` + + echo " Found $_pr_link_occurences occurences of $PR_URL in $release_notes" + + if [[ ${_pr_link_occurences} -eq 1 ]]; then + echo " Found pull request URL in $release_notes once" + RELEASE_NOTES_FOUND+="> | \\\`$path\\\` | [$release_notes](${FSHARP_REPO_URL}/$release_notes) | |" + RELEASE_NOTES_FOUND+=$'\n' + elif [[ ${_pr_link_occurences} -eq 0 ]]; then + echo " Did not find pull request URL in $release_notes" + DESCRIPTION="**No current pull request URL (${PR_URL}) found, please consider adding it**" + RELEASE_NOTES_FOUND+="> | \\\`$path\\\` | [$release_notes](${FSHARP_REPO_URL}/$release_notes) | ${DESCRIPTION} |" + RELEASE_NOTES_FOUND+=$'\n' + PULL_REQUEST_FOUND=false + fi + else + echo " Did not find $release_notes in modified files" + DESCRIPTION="**No release notes found or release notes format is not correct**" + RELEASE_NOTES_NOT_FOUND+="| \\\`$path\\\` | [$release_notes](${FSHARP_REPO_URL}/$release_notes) | ${DESCRIPTION} |" + RELEASE_NOTES_NOT_FOUND+=$'\n' + fi + else + echo " Nothing found, no release notes required" + fi + done + + echo "Done checking for release notes changes" + + if [[ $RELEASE_NOTES_NOT_FOUND != "" ]]; then + RELEASE_NOTES_MESSAGE_DETAILS+=$"@${PR_AUTHOR}," + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> [!CAUTION]" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> **No release notes found for the following paths.**" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$">" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> Please make sure to add an entry with short succint description of the change as well as link to this pull request." + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$">" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> Examples: " + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> \\\`- Respect line limit in quick info popup - https://github.com/dotnet/fsharp/pull/16208\\\`" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> \\\`- More inlines for Result module - https://github.com/dotnet/fsharp/pull/16106\\\`" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> \\\`- Miscellaneous fixes to parens analysis - https://github.com/dotnet/fsharp/pull/16262\\\`" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'**If you believe that release notes are not necessary for this PR, please add "NO_RELEASE_NOTES" label to the pull request.**' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"**You can open this PR in browser to add release notes: [open in github.dev](https://github.dev/dotnet/fsharp/pull/${PR_NUMBER})**" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+='| Change path | Release notes path | Description |' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+='| ---------------- | ------------------ | ----------- |' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+="${RELEASE_NOTES_NOT_FOUND}" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + fi + + if [[ $RELEASE_NOTES_FOUND != "" ]]; then + RELEASE_NOTES_MESSAGE_DETAILS+=$"
" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> :white_check_mark: Found changes and release notes in following paths:" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + + if [[ $PULL_REQUEST_FOUND = false ]]; then + RELEASE_NOTES_MESSAGE_DETAILS+=$"> [!WARNING]" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$"> **No PR link found in some release notes, please consider adding it.**" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + fi + + RELEASE_NOTES_MESSAGE_DETAILS+='> | Change path | Release notes path | Description |' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+='> | ---------------- | ------------------ | ----------- |' + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + RELEASE_NOTES_MESSAGE_DETAILS+="${RELEASE_NOTES_FOUND}" + RELEASE_NOTES_MESSAGE_DETAILS+=$'\n' + fi + + RELEASE_NOTES_MESSAGE+=$'\n' + + if [[ $RELEASE_NOTES_MESSAGE_DETAILS == "" ]]; then + RELEASE_NOTES_MESSAGE+=$'## :white_check_mark: No release notes required\n\n' + else + RELEASE_NOTES_MESSAGE+=$'## :heavy_exclamation_mark: Release notes required\n\n' + RELEASE_NOTES_MESSAGE+=$RELEASE_NOTES_MESSAGE_DETAILS + fi + + echo "release-notes-check-message<<$EOF" >>$GITHUB_OUTPUT + + if [[ "$OPT_OUT_RELEASE_NOTES" = true ]]; then + echo "" >>$GITHUB_OUTPUT + echo "" >>$GITHUB_OUTPUT + echo "## :warning: Release notes required, but author opted out" >>$GITHUB_OUTPUT + echo "" >>$GITHUB_OUTPUT + echo "" >>$GITHUB_OUTPUT + echo "> [!WARNING]" >>$GITHUB_OUTPUT + echo "> **Author opted out of release notes, check is disabled for this pull request.**" >>$GITHUB_OUTPUT + echo "> cc @dotnet/fsharp-team-msft" >>$GITHUB_OUTPUT + else + echo "${RELEASE_NOTES_MESSAGE}" >>$GITHUB_OUTPUT + fi + + echo "$EOF" >>$GITHUB_OUTPUT + + if [[ $RELEASE_NOTES_NOT_FOUND != "" && ${OPT_OUT_RELEASE_NOTES} != true ]]; then + exit 1 + fi + # Did bot already commented the PR? + - name: Find Comment + if: success() || failure() + uses: peter-evans/find-comment@v2.4.0 + id: fc + with: + issue-number: ${{github.event.pull_request.number}} + comment-author: 'github-actions[bot]' + body-includes: '' + # If not, create a new comment + - name: Create comment + if: steps.fc.outputs.comment-id == '' && (success() || failure()) + uses: actions/github-script@v6 + with: + github-token: ${{ github.token }} + script: | + const comment = await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `${{steps.release_notes_changes.outputs.release-notes-check-message}}` + }); + return comment.data.id; + # If yes, update the comment + - name: Update comment + if: steps.fc.outputs.comment-id != '' && (success() || failure()) + uses: actions/github-script@v6 + with: + github-token: ${{ github.token }} + script: | + const comment = await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: ${{steps.fc.outputs.comment-id}}, + body: `${{steps.release_notes_changes.outputs.release-notes-check-message}}` + }); + return comment.data.id; \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d16b15a6ed0..d8ee497da76 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -281,9 +281,11 @@ stages: # Check whether package with current version has been published to nuget.org # We will try to restore both FSharp.Core and FCS and if restore is _successful_, package version needs to be bumped. - # NOTE: This CI check should only run on the release branches. + # NOTE: The check now runs on all branches (not just release), + # because we want to catch cases when version is desynched and we didn't update it. + # It is also helping the release notes automation to be up to date with packages versions. - job: Check_Published_Package_Versions - condition: or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), or(startsWith(variables['System.PullRequest.SourceBranch'], 'release/dev'), startsWith(variables['System.PullRequest.TargetBranch'], 'release/dev'))) + # condition: or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), or(startsWith(variables['System.PullRequest.SourceBranch'], 'release/dev'), startsWith(variables['System.PullRequest.TargetBranch'], 'release/dev'))) pool: vmImage: $(UbuntuMachineQueueName) strategy: diff --git a/docs/release-notes/FSharp.Compiler.Service/8.0.200.md b/docs/release-notes/FSharp.Compiler.Service/8.0.200.md new file mode 100644 index 00000000000..33e81141302 --- /dev/null +++ b/docs/release-notes/FSharp.Compiler.Service/8.0.200.md @@ -0,0 +1 @@ +- Miscellaneous fixes to parens analysis - https://github.com/dotnet/fsharp/pull/16262 \ No newline at end of file diff --git a/docs/release-notes/FSharp.Core/8.0.200.md b/docs/release-notes/FSharp.Core/8.0.200.md new file mode 100644 index 00000000000..8bed6454108 --- /dev/null +++ b/docs/release-notes/FSharp.Core/8.0.200.md @@ -0,0 +1 @@ +- More inlines for Result module - https://github.com/dotnet/fsharp/pull/16106 \ No newline at end of file diff --git a/docs/release-notes/Language/preview.md b/docs/release-notes/Language/preview.md new file mode 100644 index 00000000000..7d9996a870e --- /dev/null +++ b/docs/release-notes/Language/preview.md @@ -0,0 +1 @@ +- Feature: Better unmanaged structs handling - https://github.com/dotnet/fsharp/pull/12154 \ No newline at end of file diff --git a/eng/Versions.props b/eng/Versions.props index c96ae7ba999..d09ec8ccaf6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -12,10 +12,11 @@ beta + 8 0 - 100 + 200 0 @@ -55,8 +56,9 @@ $(FSToolsMajorVersion).$(FSToolsMinorVersion).$(FSToolsBuildVersion).$(FSToolsRevisionVersion) + 17 - 8 + 9 $(VSMajorVersion).0 $(VSMajorVersion).$(VSMinorVersion).0 $(VSAssemblyVersionPrefix).0 diff --git a/src/FSharp.Core/prim-types-prelude.fs b/src/FSharp.Core/prim-types-prelude.fs index 63c370ba332..9a002450382 100644 --- a/src/FSharp.Core/prim-types-prelude.fs +++ b/src/FSharp.Core/prim-types-prelude.fs @@ -119,3 +119,4 @@ namespace Microsoft.FSharp.Core type voidptr = (# "void*" #) type ilsigptr<'T> = (# "!0*" #) + diff --git a/vsintegration/src/Directory.Build.props b/vsintegration/src/Directory.Build.props index f7a21adf80c..af52f02d17b 100644 --- a/vsintegration/src/Directory.Build.props +++ b/vsintegration/src/Directory.Build.props @@ -10,3 +10,4 @@ +