diff --git a/.editorconfig b/.editorconfig index 26a8ca5..3ba6837 100644 --- a/.editorconfig +++ b/.editorconfig @@ -30,6 +30,8 @@ indent_size = 2 # Dotnet code style settings: [*.{cs,vb}] +tab_width = 4 + # Sort using and Import directives with System.* appearing first dotnet_sort_system_directives_first = true # Avoid "this." and "Me." if not necessary @@ -57,7 +59,16 @@ dotnet_style_require_accessibility_modifiers = omit_if_default:error # IDE0040: Add accessibility modifiers dotnet_diagnostic.IDE0040.severity = error +# IDE1100: Error reading content of source file 'Project.TargetFrameworkMoniker' (i.e. from ThisAssembly) +dotnet_diagnostic.IDE1100.severity = none + [*.cs] +# Top-level files are definitely OK +csharp_using_directive_placement = outside_namespace:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent + # Prefer "var" everywhere csharp_style_var_for_built_in_types = true:suggestion csharp_style_var_when_type_is_apparent = true:suggestion @@ -89,9 +100,15 @@ csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_anonymous_types = true # Test settings -[**/*Tests*/*{.cs,.vb}] +[**/*Tests*/**{.cs,.vb}] # xUnit1013: Public method should be marked as test. Allows using records as test classes dotnet_diagnostic.xUnit1013.severity = none +# CS9113: Parameter is unread (usually, ITestOutputHelper) +dotnet_diagnostic.CS9113.severity = none + +# Default severity for analyzer diagnostics with category 'Style' +dotnet_analyzer_diagnostic.category-Style.severity = none + # VSTHRD200: Use "Async" suffix for async methods dotnet_diagnostic.VSTHRD200.severity = none diff --git a/.gitattributes b/.gitattributes index 7c37579..3095556 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,24 +1,9 @@ -# sln, csproj files (and friends) are always CRLF, even on linux -*.sln text eol=crlf -*.proj text eol=crlf -*.csproj text eol=crlf +# normalize by default +* text=auto encoding=UTF-8 +*.sh text eol=lf +*.sbn eol=lf # These are windows specific files which we may as well ensure are # always crlf on checkout *.bat text eol=crlf *.cmd text eol=crlf - -# Opt in known filetypes to always normalize line endings on checkin -# and always use native endings on checkout -*.c text -*.config text -*.h text -*.cs text -*.md text -*.tt text -*.txt text - -# Some must always be checked out as lf so enforce that for those files -# If these are not lf then bash/cygwin on windows will not be able to -# excute the files -*.sh text eol=lf \ No newline at end of file diff --git a/.github/actions/dotnet/action.yml b/.github/actions/dotnet/action.yml new file mode 100644 index 0000000..c876ae3 --- /dev/null +++ b/.github/actions/dotnet/action.yml @@ -0,0 +1,35 @@ +name: โš™ dotnet +description: Configures dotnet if the repo/org defines the DOTNET custom property + +runs: + using: composite + steps: + - name: ๐Ÿ”Ž dotnet + id: dotnet + shell: bash + run: | + VERSIONS=$(gh api repos/${{ github.repository }}/properties/values | jq -r '.[] | select(.property_name == "DOTNET") | .value') + # Remove extra whitespace from VERSIONS + VERSIONS=$(echo "$VERSIONS" | tr -s ' ' | tr -d ' ') + # Convert comma-separated to newline-separated + NEWLINE_VERSIONS=$(echo "$VERSIONS" | tr ',' '\n') + # Validate versions + while IFS= read -r version; do + if ! [[ $version =~ ^[0-9]+(\.[0-9]+(\.[0-9]+)?)?(\.x)?$ ]]; then + echo "Error: Invalid version format: $version" + exit 1 + fi + done <<< "$NEWLINE_VERSIONS" + # Write multiline output to $GITHUB_OUTPUT + { + echo 'versions<> $GITHUB_OUTPUT + + - name: โš™ dotnet + if: steps.dotnet.outputs.versions != '' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + ${{ steps.dotnet.outputs.versions }} diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a3b1808..11c5d7d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,5 +7,42 @@ updates: directory: / schedule: interval: daily - ignore: - - dependency-name: "Microsoft.CodeAnalysis.*" + groups: + Azure: + patterns: + - "Azure*" + - "Microsoft.Azure*" + Identity: + patterns: + - "System.IdentityModel*" + - "Microsoft.IdentityModel*" + System: + patterns: + - "System*" + exclude-patterns: + - "System.IdentityModel*" + Extensions: + patterns: + - "Microsoft.Extensions*" + exclude-patterns: + - "Microsoft.Extensions.AI*" + ExtensionsAI: + patterns: + - "Microsoft.Extensions.AI*" + Web: + patterns: + - "Microsoft.AspNetCore*" + Tests: + patterns: + - "Microsoft.NET.Test*" + - "xunit*" + - "coverlet*" + ThisAssembly: + patterns: + - "ThisAssembly*" + ProtoBuf: + patterns: + - "protobuf-*" + Spectre: + patterns: + - "Spectre.Console*" diff --git a/.github/release.yml b/.github/release.yml index 9a018cd..c178589 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -8,7 +8,6 @@ changelog: - invalid - wontfix - need info - - docs - techdebt authors: - devlooped-bot @@ -24,6 +23,7 @@ changelog: - title: ๐Ÿ“ Documentation updates labels: - docs + - documentation - title: ๐Ÿ”จ Other labels: - '*' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0781a30..ab80b8e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,19 +4,31 @@ name: build on: workflow_dispatch: + inputs: + configuration: + type: choice + description: Configuration + options: + - Release + - Debug push: branches: [ main, dev, 'dev/*', 'feature/*', 'rel/*' ] paths-ignore: - changelog.md - - code-of-conduct.md - - security.md - - support.md - readme.md pull_request: types: [opened, synchronize, reopened] env: DOTNET_NOLOGO: true + PackOnBuild: true + GeneratePackageOnBuild: true + VersionPrefix: 42.42.${{ github.run_number }} + VersionLabel: ${{ github.ref }} + GH_TOKEN: ${{ secrets.GH_TOKEN }} + MSBUILDTERMINALLOGGER: auto + Configuration: ${{ github.event.inputs.configuration || 'Release' }} + SLEET_FEED_URL: ${{ vars.SLEET_FEED_URL }} defaults: run: @@ -29,7 +41,7 @@ jobs: matrix: ${{ steps.lookup.outputs.matrix }} steps: - name: ๐Ÿค˜ checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: ๐Ÿ”Ž lookup id: lookup @@ -48,44 +60,49 @@ jobs: os: ${{ fromJSON(needs.os-matrix.outputs.matrix) }} steps: - name: ๐Ÿค˜ checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - - name: ๐Ÿ™ build - run: dotnet build -m:1 -p:VersionLabel="$GITHUB_REF.$GITHUB_RUN_NUMBER" + - name: โš™ dotnet + uses: devlooped/actions-dotnet-env@v1 - - name: โš™ GNU grep - if: matrix.os == 'macOS-latest' - run: | - brew install grep - echo 'export PATH="/usr/local/opt/grep/libexec/gnubin:$PATH"' >> .bash_profile + - name: ๐Ÿ™ build + run: dotnet build -m:1 -bl:build.binlog - name: ๐Ÿงช test - uses: ./.github/workflows/test + shell: pwsh + run: dnx --yes retest -- --no-build - - name: ๐Ÿ“ฆ pack - run: dotnet pack -m:1 -p:VersionLabel="$GITHUB_REF.$GITHUB_RUN_NUMBER" + - name: ๐Ÿ› logs + uses: actions/upload-artifact@v4 + if: runner.debug && always() + with: + name: logs + path: '*.binlog' - # Only push CI package to sleet feed if building on ubuntu (fastest) - name: ๐Ÿš€ sleet env: SLEET_CONNECTION: ${{ secrets.SLEET_CONNECTION }} if: env.SLEET_CONNECTION != '' run: | - dotnet tool install -g --version 4.0.18 sleet + dotnet tool update sleet -g --allow-downgrade --version $(curl -s --compressed ${{ vars.SLEET_FEED_URL }} | jq '.["sleet:version"]' -r) sleet push bin --config none -f --verbose -p "SLEET_FEED_CONTAINER=nuget" -p "SLEET_FEED_CONNECTIONSTRING=${{ secrets.SLEET_CONNECTION }}" -p "SLEET_FEED_TYPE=azure" || echo "No packages found" dotnet-format: runs-on: ubuntu-latest - needs: build steps: - name: ๐Ÿค˜ checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 + - name: โš™ dotnet + uses: devlooped/actions-dotnet-env@v1 + - name: โœ“ ensure format - run: dotnet format --verify-no-changes -v:diag --exclude ~/.nuget + run: | + dotnet format whitespace --verify-no-changes -v:diag --exclude ~/.nuget + dotnet format style --verify-no-changes -v:diag --exclude ~/.nuget diff --git a/.github/workflows/changelog.config b/.github/workflows/changelog.config index cd34ee7..e47bccd 100644 --- a/.github/workflows/changelog.config +++ b/.github/workflows/changelog.config @@ -1,7 +1,7 @@ usernames-as-github-logins=true issues_wo_labels=true pr_wo_labels=true -exclude-labels=bydesign,dependencies,duplicate,question,invalid,wontfix,need info,docs +exclude-labels=bydesign,dependencies,duplicate,discussion,question,invalid,wontfix,need info,docs enhancement-label=:sparkles: Implemented enhancements: bugs-label=:bug: Fixed bugs: issues-label=:hammer: Other: diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index b120b73..ca50e5a 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -17,7 +17,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} - name: ๐Ÿค˜ checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 ref: main diff --git a/.github/workflows/dotnet-env.yml b/.github/workflows/dotnet-env.yml new file mode 100644 index 0000000..a76d0fd --- /dev/null +++ b/.github/workflows/dotnet-env.yml @@ -0,0 +1,44 @@ +name: dotnet-env +on: + workflow_dispatch: + push: + branches: + - main + paths: + - '**/*.*proj' + +jobs: + which-dotnet: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: ๐Ÿค– defaults + uses: devlooped/actions-bot@v1 + with: + name: ${{ secrets.BOT_NAME }} + email: ${{ secrets.BOT_EMAIL }} + gh_token: ${{ secrets.GH_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: ๐Ÿค˜ checkout + uses: actions/checkout@v4 + with: + token: ${{ env.GH_TOKEN }} + + - name: ๐ŸคŒ dotnet + uses: devlooped/actions-which-dotnet@v1 + + - name: โœ pull request + uses: peter-evans/create-pull-request@v7 + with: + base: main + branch: which-dotnet + delete-branch: true + labels: dependencies + title: "โš™ Update dotnet versions" + body: "Update dotnet versions" + commit-message: "Update dotnet versions" + token: ${{ env.GH_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/dotnet-file-core.yml b/.github/workflows/dotnet-file-core.yml new file mode 100644 index 0000000..824f52c --- /dev/null +++ b/.github/workflows/dotnet-file-core.yml @@ -0,0 +1,95 @@ +# Synchronizes .netconfig-configured files with dotnet-file +name: dotnet-file-core +on: + workflow_call: + secrets: + BOT_NAME: + required: false + BOT_EMAIL: + required: false + GH_TOKEN: + required: false + +env: + DOTNET_NOLOGO: true + +defaults: + run: + shell: pwsh + +jobs: + sync: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - name: ๐Ÿค– defaults + uses: devlooped/actions-bot@v1 + with: + name: ${{ secrets.BOT_NAME }} + email: ${{ secrets.BOT_EMAIL }} + gh_token: ${{ secrets.GH_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: ๐Ÿค˜ checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + token: ${{ env.GH_TOKEN }} + + - name: โŒ› rate + if: github.event_name != 'workflow_dispatch' + run: | + # add random sleep since we run on fixed schedule + sleep (get-random -max 60) + # get currently authenticated user rate limit info + $rate = gh api rate_limit | convertfrom-json | select -expandproperty rate + # if we don't have at least 100 requests left, wait until reset + if ($rate.remaining -lt 10) { + $wait = ($rate.reset - (Get-Date (Get-Date).ToUniversalTime() -UFormat %s)) + echo "Rate limit remaining is $($rate.remaining), waiting for $($wait / 1000) seconds to reset" + sleep $wait + $rate = gh api rate_limit | convertfrom-json | select -expandproperty rate + echo "Rate limit has reset to $($rate.remaining) requests" + } + + - name: ๐Ÿ”„ sync + run: | + dotnet tool update -g dotnet-gcm + # store credentials in plaintext for linux compat + git config --local credential.credentialStore plaintext + dotnet gcm store --protocol=https --host=github.com --username=$env:GITHUB_ACTOR --password=$env:GH_TOKEN + gh auth status + + dotnet tool update -g dotnet-file + $changelog = "$([System.IO.Path]::GetTempPath())dotnet-file.md" + dotnet file sync -c:$changelog + if (test-path $changelog) { + echo 'CHANGES<> $env:GITHUB_ENV + cat $changelog >> $env:GITHUB_ENV + echo 'EOF' >> $env:GITHUB_ENV + cat $changelog + } else { + echo 'No changelog was generated' + } + + - name: +Mแ includes + uses: devlooped/actions-includes@v1 + with: + validate: false + + - name: โœ pull request + uses: peter-evans/create-pull-request@v8 + with: + base: main + branch: dotnet-file-sync + delete-branch: true + labels: dependencies + author: ${{ env.BOT_AUTHOR }} + committer: ${{ env.BOT_AUTHOR }} + commit-message: โฌ†๏ธ Bump files with dotnet-file sync + + ${{ env.CHANGES }} + title: "โฌ†๏ธ Bump files with dotnet-file sync" + body: ${{ env.CHANGES }} + token: ${{ env.GH_TOKEN }} diff --git a/.github/workflows/dotnet-file.yml b/.github/workflows/dotnet-file.yml index 083f24d..402f6ba 100644 --- a/.github/workflows/dotnet-file.yml +++ b/.github/workflows/dotnet-file.yml @@ -12,5 +12,10 @@ env: jobs: run: + permissions: + contents: write uses: devlooped/oss/.github/workflows/dotnet-file-core.yml@main - secrets: inherit \ No newline at end of file + secrets: + BOT_NAME: ${{ secrets.BOT_NAME }} + BOT_EMAIL: ${{ secrets.BOT_EMAIL }} + GH_TOKEN: ${{ secrets.GH_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/includes.yml b/.github/workflows/includes.yml index b806653..fc6dbeb 100644 --- a/.github/workflows/includes.yml +++ b/.github/workflows/includes.yml @@ -5,12 +5,16 @@ on: branches: - 'main' paths: - - '**.md' + - '**.md' - '!changelog.md' + - 'osmfeula.txt' jobs: includes: runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write steps: - name: ๐Ÿค– defaults uses: devlooped/actions-bot@v1 @@ -21,20 +25,40 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} - name: ๐Ÿค˜ checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: token: ${{ env.GH_TOKEN }} - name: +Mแ includes - uses: devlooped/actions-include@v1 + uses: devlooped/actions-includes@v1 + + - name: ๐Ÿ“ OSMF EULA + shell: pwsh + run: | + $file = "osmfeula.txt" + $props = "src/Directory.Build.props" + if (-not (test-path $file) -or -not (test-path $props)) { + exit 0 + } + + $product = dotnet msbuild $props -getproperty:Product + if (-not $product) { + write-error 'To use OSMF EULA, ensure the $(Product) property is set in Directory.props' + exit 1 + } + + ((get-content -raw $file) -replace '\$product\$',$product).trim() | set-content $file - name: โœ pull request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v8 with: + add-paths: | + **.md + *.txt base: main branch: markdown-includes delete-branch: true - labels: docs + labels: dependencies author: ${{ env.BOT_AUTHOR }} committer: ${{ env.BOT_AUTHOR }} commit-message: +Mแ includes diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bd83ada..035d811 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,30 +5,56 @@ name: publish on: release: - types: [released] + types: [prereleased, released] env: DOTNET_NOLOGO: true Configuration: Release - + PackOnBuild: true + GeneratePackageOnBuild: true + VersionLabel: ${{ github.ref }} + GH_TOKEN: ${{ secrets.GH_TOKEN }} + MSBUILDTERMINALLOGGER: auto + SLEET_FEED_URL: https://api.nuget.org/v3/index.json + jobs: publish: - runs-on: ubuntu-latest + runs-on: ${{ vars.PUBLISH_AGENT || 'ubuntu-latest' }} steps: - name: ๐Ÿค˜ checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 + - name: โš™ dotnet + uses: devlooped/actions-dotnet-env@v1 + - name: ๐Ÿ™ build - run: dotnet build -m:1 -p:version=${GITHUB_REF#refs/*/v} + run: dotnet build -m:1 -bl:build.binlog - name: ๐Ÿงช test - uses: ./.github/workflows/test + shell: pwsh + run: dnx --yes retest -- --no-build - - name: ๐Ÿ“ฆ pack - run: dotnet pack -m:1 -p:version=${GITHUB_REF#refs/*/v} + - name: ๐Ÿ› logs + uses: actions/upload-artifact@v4 + if: runner.debug && always() + with: + name: logs + path: '*.binlog' - name: ๐Ÿš€ nuget - run: dotnet nuget push ./bin/**/*.nupkg -s https://api.nuget.org/v3/index.json -k ${{secrets.NUGET_API_KEY}} --skip-duplicate + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + if: ${{ env.NUGET_API_KEY != '' && github.event.action != 'prereleased' }} + working-directory: bin + run: dotnet nuget push *.nupkg -s https://api.nuget.org/v3/index.json -k ${{secrets.NUGET_API_KEY}} --skip-duplicate + + - name: ๐Ÿš€ sleet + env: + SLEET_CONNECTION: ${{ secrets.SLEET_CONNECTION }} + if: env.SLEET_CONNECTION != '' + run: | + dotnet tool update sleet -g --allow-downgrade --version $(curl -s --compressed ${{ vars.SLEET_FEED_URL }} | jq '.["sleet:version"]' -r) + sleet push bin --config none -f --verbose -p "SLEET_FEED_CONTAINER=nuget" -p "SLEET_FEED_CONNECTIONSTRING=${{ secrets.SLEET_CONNECTION }}" -p "SLEET_FEED_TYPE=azure" || echo "No packages found" diff --git a/.github/workflows/sponsor.yml b/.github/workflows/sponsor.yml deleted file mode 100644 index 9e47191..0000000 --- a/.github/workflows/sponsor.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: sponsor ๐Ÿ’œ -on: - issues: - types: [opened, edited, reopened] - pull_request: - types: [opened, edited, synchronize, reopened] - -jobs: - sponsor: - runs-on: ubuntu-latest - continue-on-error: true - env: - token: ${{ secrets.GH_TOKEN }} - if: ${{ !endsWith(github.event.sender.login, '[bot]') && !endsWith(github.event.sender.login, 'bot') }} - steps: - - name: ๐Ÿค˜ checkout - if: env.token != '' - uses: actions/checkout@v2 - - - name: ๐Ÿ’œ sponsor - if: env.token != '' - uses: devlooped/actions-sponsor@main - with: - token: ${{ env.token }} diff --git a/.github/workflows/test/action.yml b/.github/workflows/test/action.yml deleted file mode 100644 index 4a7dbae..0000000 --- a/.github/workflows/test/action.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: test -description: runs dotnet tests with retry -runs: - using: "composite" - steps: - - name: ๐Ÿงช test - shell: bash --noprofile --norc {0} - env: - LC_ALL: en_US.utf8 - run: | - [ -f .bash_profile ] && source .bash_profile - counter=0 - exitcode=0 - reset="\e[0m" - warn="\e[0;33m" - while [ $counter -lt 6 ] - do - # run test and forward output also to a file in addition to stdout (tee command) - if [ $filter ] - then - echo -e "${warn}Retry $counter for $filter ${reset}" - dotnet test --no-build -m:1 --blame-hang --blame-hang-timeout 5m --filter=$filter | tee ./output.log - else - dotnet test --no-build -m:1 --blame-hang --blame-hang-timeout 5m | tee ./output.log - fi - # capture dotnet test exit status, different from tee - exitcode=${PIPESTATUS[0]} - if [ $exitcode == 0 ] - then - exit 0 - fi - # cat output, get failed test names, remove trailing whitespace, sort+dedupe, join as FQN~TEST with |, remove trailing |. - filter=$(cat ./output.log | grep -o -P '(?<=\sFailed\s)[\w\._]*' | sed 's/ *$//g' | sort -u | awk 'BEGIN { ORS="|" } { print("FullyQualifiedName~" $0) }' | grep -o -P '.*(?=\|$)') - ((counter++)) - done - exit $exitcode diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml new file mode 100644 index 0000000..56ff299 --- /dev/null +++ b/.github/workflows/triage.yml @@ -0,0 +1,103 @@ +name: 'triage' +on: + schedule: + - cron: '42 0 * * *' + + workflow_dispatch: + # Manual triggering through the GitHub UI, API, or CLI + inputs: + daysBeforeClose: + description: "Days before closing stale or need info issues" + required: true + default: "30" + daysBeforeStale: + description: "Days before labeling stale" + required: true + default: "180" + daysSinceClose: + description: "Days since close to lock" + required: true + default: "30" + daysSinceUpdate: + description: "Days since update to lock" + required: true + default: "30" + +permissions: + actions: write # For managing the operation state cache + issues: write + contents: read + +jobs: + stale: + # Do not run on forks + if: github.repository_owner == 'devlooped' + runs-on: ubuntu-latest + steps: + - name: โŒ› rate + shell: pwsh + if: github.event_name != 'workflow_dispatch' + env: + GH_TOKEN: ${{ secrets.DEVLOOPED_TOKEN }} + run: | + # add random sleep since we run on fixed schedule + $wait = get-random -max 180 + echo "Waiting random $wait seconds to start" + sleep $wait + # get currently authenticated user rate limit info + $rate = gh api rate_limit | convertfrom-json | select -expandproperty rate + # if we don't have at least 100 requests left, wait until reset + if ($rate.remaining -lt 100) { + $wait = ($rate.reset - (Get-Date (Get-Date).ToUniversalTime() -UFormat %s)) + echo "Rate limit remaining is $($rate.remaining), waiting for $($wait / 1000) seconds to reset" + sleep $wait + $rate = gh api rate_limit | convertfrom-json | select -expandproperty rate + echo "Rate limit has reset to $($rate.remaining) requests" + } + + - name: โœ๏ธ stale labeler + # pending merge: https://github.com/actions/stale/pull/1176 + uses: kzu/stale@c8450312ba97b204bf37545cb249742144d6ca69 + with: + ascending: true # Process the oldest issues first + stale-issue-label: 'stale' + stale-issue-message: | + Due to lack of recent activity, this issue has been labeled as 'stale'. + It will be closed if no further activity occurs within ${{ fromJson(inputs.daysBeforeClose || 30 ) }} more days. + Any new comment will remove the label. + close-issue-message: | + This issue will now be closed since it has been labeled 'stale' without activity for ${{ fromJson(inputs.daysBeforeClose || 30 ) }} days. + days-before-stale: ${{ fromJson(inputs.daysBeforeStale || 180) }} + days-before-close: ${{ fromJson(inputs.daysBeforeClose || 30 ) }} + days-before-pr-close: -1 # Do not close PRs labeled as 'stale' + exempt-all-milestones: true + exempt-all-assignees: true + exempt-issue-labels: priority,sponsor,backed + exempt-authors: kzu + + - name: ๐Ÿค˜ checkout actions + uses: actions/checkout@v4 + with: + repository: 'microsoft/vscode-github-triage-actions' + ref: v42 + + - name: โš™ install actions + run: npm install --production + + - name: ๐Ÿ”’ issues locker + uses: ./locker + with: + token: ${{ secrets.DEVLOOPED_TOKEN }} + ignoredLabel: priority + daysSinceClose: ${{ fromJson(inputs.daysSinceClose || 30) }} + daysSinceUpdate: ${{ fromJson(inputs.daysSinceUpdate || 30) }} + + - name: ๐Ÿ”’ need info closer + uses: ./needs-more-info-closer + with: + token: ${{ secrets.DEVLOOPED_TOKEN }} + label: 'need info' + closeDays: ${{ fromJson(inputs.daysBeforeClose || 30) }} + closeComment: "This issue has been closed automatically because it needs more information and has not had recent activity.\n\nHappy Coding!" + pingDays: 80 + pingComment: "Hey @${assignee}, this issue might need further attention.\n\n@${author}, you can help us out by closing this issue if the problem no longer exists, or adding more information." \ No newline at end of file diff --git a/.gitignore b/.gitignore index 242945b..0fe79fb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,15 @@ obj artifacts pack TestResults +results +BenchmarkDotNet.Artifacts +/app .vs .vscode +.genaiscript +.idea +local.settings.json +.env *.suo *.sdf @@ -29,5 +36,6 @@ node_modules _site .jekyll-metadata .jekyll-cache +.sass-cache Gemfile.lock package-lock.json diff --git a/.netconfig b/.netconfig index 2c5c6d0..1cedd8e 100644 --- a/.netconfig +++ b/.netconfig @@ -14,63 +14,58 @@ skip [file ".editorconfig"] url = https://github.com/devlooped/oss/blob/main/.editorconfig - sha = 448cf45a26e068fe5d7164ea48d1dc8bf620df46 - etag = 897634b9ba05c00e8ef35b24533d31bc43a5299be5a64e240109ba4c00fcad15 + sha = a62c45934ac2952f2f5d54d8aea4a7ebc1babaff + etag = b5e919b472a52d4b522f86494f0f2c0ba74a6d9601454e20e4cbaf744317ff62 weak [file ".gitattributes"] url = https://github.com/devlooped/oss/blob/main/.gitattributes - sha = 0683ee777d7d878d4bf013d7deea352685135a05 - etag = 7acb32f5fa6d4ccd9c824605a7c2b8538497f0068c165567807d393dcf4d6bb7 + sha = 4a9aa321c4982b83c185cf8dffed181ff84667d5 + etag = 09cad18280ed04b67f7f87591e5481510df04d44c3403231b8af885664d8fd58 weak [file ".github/dependabot.yml"] url = https://github.com/devlooped/oss/blob/main/.github/dependabot.yml - sha = 4f070a477b4162a280f02722ae666376ae4fcc71 - etag = 35f2134fff3b0235ff8dac8618a76198c8ef533ad2f29628bbb435cd1134d638 + sha = e733294084fb3e75d517a2e961e87df8faae7dc6 + etag = 3bf8d9214a15c049ca5cfe80d212a8cbe4753b8a638a9804ef73d34c7def9618 weak [file ".github/workflows/build.yml"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/build.yml - sha = 7e3288c3c7746354edc2836e4fb71f11e17db83c - etag = bea8f881a2c7a02de70a201806edb432f7185d39df762f76efdefe392ea019a5 + sha = 7f5f9ee9f362f7e8f951d618f8f799033550e687 + etag = a04ce46114292f5c0e76bc1f260381b174c93d6f264749dfacbfc892238bec73 weak [file ".github/workflows/changelog.yml"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/changelog.yml - sha = a4b66eb5f4dfb9704502f19f59ba33cb4855188c - etag = 54c0b571648b1055beb3ddac180b34e93a9869b9f0277de306901b2c1dbe0b2c + sha = 5fb172362c767bef7c36478f1a6bdc264723f8f9 + etag = ad1efa56d6024ee1add2bcda81a7e4e38d0e9069473c6ff70374d5ce06af1f5a weak [file ".github/workflows/dotnet-file.yml"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/dotnet-file.yml - sha = f08c3f28e46e28eb31e70846d65e57aa9553ce56 - etag = 567444486383d032c1c5fbc538f07e860f92b1d08c66ac6ffb1db64ca539251c + sha = 8fa147d4799d73819040736c399d0b1db2c2d86c + etag = 1ca805a23656e99c03f9d478dba8ccef6e571f5de2ac0e9bb7e3c5216c99a694 weak [file ".github/workflows/includes.yml"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/includes.yml - sha = f08c3f28e46e28eb31e70846d65e57aa9553ce56 - etag = 884175b3f80b39edc1a23c6a34d58aa3c481432d4f20938f9a834dd918ef283d + sha = 06628725a6303bb8c4cf3076a384fc982a91bc0b + etag = 478f91d4126230e57cc601382da1ba23f9daa054645b4af89800d8dd862e64fd weak [file ".github/workflows/publish.yml"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/publish.yml - sha = d3022567c9ef2bc9461511e53b8abe065afdf03b - etag = 58601b5a71c805647ab26e84053acdfb8d174eaa93330487af8a5503753c5707 - weak -[file ".github/workflows/test/action.yml"] - url = https://github.com/devlooped/oss/blob/main/.github/workflows/test/action.yml - sha = 9a1b07589b9bde93bc12528e9325712a32dec418 - etag = b54216ac431a83ce5477828d391f02046527e7f6fffd21da1d03324d352c3efb + sha = 7f5f9ee9f362f7e8f951d618f8f799033550e687 + etag = c60411d1aa4e98e7f69e2d34cbccb8eb7e387ec11f6f8e78ee8d8b92122d7025 weak [file ".gitignore"] url = https://github.com/devlooped/oss/blob/main/.gitignore - sha = c78868eba59a3e04602434684f9eac241fef13fb - etag = 1c1705a3f0ed65e33c9133996ebaa100aa445a8b968b2904ad48fef938702006 + sha = 3776526342afb3f57da7e80f2095e5fdca3c31c9 + etag = 11767f73556aa4c6c8bcc153b77ee8e8114f99fa3b885b0a7d66d082f91e77b3 weak [file "Directory.Build.rsp"] url = https://github.com/devlooped/oss/blob/main/Directory.Build.rsp - sha = ae25fae9d7daf0cb47d537ba870914aa3052f0c9 - etag = 6a6c6e1d3895df953abf14c82b0899e3eea75cdcd679f6212dcfea15183d73d6 + sha = 0f7f7f7e8a29de9b535676f75fe7c67e629a5e8c + etag = 0ccae83fc51f400bfd7058170bfec7aba11455e24a46a0d7e6a358da6486e255 weak [file "_config.yml"] url = https://github.com/devlooped/oss/blob/main/_config.yml - sha = fa83a5161ba52bc5d510ce0ba75ee0b1f8d4bc63 - etag = 9139148f845adf503fd3c3c140eb64421fc476a1f9c027fc50825c0efb05f557 + sha = 68b409c486842062e0de0e5b11e6fdb7cd12d6e2 + etag = d608aa0ddaedc2d8a87260f50756e8d8314964ad4671b76bd085bcb458757010 weak [file "assets/css/style.scss"] url = https://github.com/devlooped/oss/blob/main/assets/css/style.scss @@ -84,13 +79,13 @@ weak [file "src/Directory.Build.props"] url = https://github.com/devlooped/oss/blob/main/src/Directory.Build.props - sha = ef8e7fa7593ded91d871d30eeebd0dc79f679159 - etag = 1d5ec6bdb8b12c13635a11364dcfe54aefb82cc171f332a8d536aa35476222d5 + sha = 0ff8b7b79a82112678326d1dc5543ed890311366 + etag = 3ebde0a8630d526b80f15801179116e17a857ff880a4442e7db7b075efa4fd63 weak [file "src/Directory.Build.targets"] url = https://github.com/devlooped/oss/blob/main/src/Directory.Build.targets - sha = b9fb0a7d34d6c16fb404f9dff4aac6789ef08a00 - etag = 852b16129d2c681ad6ec86ff56b256541e0ce0961eb3a9492e0ead89ffe5a6bd + sha = 4339749ef4b8f66def75931df09ef99c149f8421 + etag = 8b4492765755c030c4c351e058a92f53ab493cab440c1c0ef431f6635c4dae0e weak [file ".github/workflows/combine-prs.yml"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/combine-prs.yml @@ -104,16 +99,31 @@ weak [file ".github/release.yml"] url = https://github.com/devlooped/oss/blob/main/.github/release.yml - sha = 1afd173fe8f81b510c597737b0d271218e81fa73 - etag = 482dc2c892fc7ce0cb3a01eb5d9401bee50ddfb067d8cb85873555ce63cf5438 + sha = 0c23e24704625cf75b2cb1fdc566cef7e20af313 + etag = 310df162242c95ed19ed12e3c96a65f77e558b46dced676ad5255eb12caafe75 weak [file ".github/workflows/changelog.config"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/changelog.config - sha = 055a8b7c94b74ae139cce919d60b83976d2a9942 - etag = ddb17acb5872e9e69a76f9dec0ca590f25382caa2ccf750df058dcabb674db2b - weak -[file ".github/workflows/sponsor.yml"] - url = https://github.com/devlooped/oss/blob/main/.github/workflows/sponsor.yml - sha = 8990ebb36199046e0b8098bad9e46dcef739c56e - etag = e1dc114d2e8b57d50649989d32dbf0c9080ec77da3738a4cc79e9256d6ca5d3e + sha = 08d83cb510732f861416760d37702f9f55bd7f9e + etag = 556a28914eeeae78ca924b1105726cdaa211af365671831887aec81f5f4301b4 + weak +[file ".github/actions/dotnet/action.yml"] + url = https://github.com/devlooped/oss/blob/main/.github/actions/dotnet/action.yml + sha = f2b690ce307acb76c5b8d7faec1a5b971a93653e + etag = 27ea11baa2397b3ec9e643a935832da97719c4e44215cfd135c49cad4c29373f + weak +[file ".github/workflows/dotnet-env.yml"] + url = https://github.com/devlooped/oss/blob/main/.github/workflows/dotnet-env.yml + sha = 77e83f238196d2723640abef0c7b6f43994f9747 + etag = fcb9759a96966df40dcd24906fd328ddec05953b7e747a6bb8d0d1e4c3865274 + weak +[file ".github/workflows/dotnet-file-core.yml"] + url = https://github.com/devlooped/oss/blob/main/.github/workflows/dotnet-file-core.yml + sha = d00364faaa84c414b868c0758b9e1a5fc0520dcc + etag = d3b7d8ca69e6d22066a2348f02b409e2d6fb900f5039f68940c14e4ce6021826 + weak +[file ".github/workflows/triage.yml"] + url = https://github.com/devlooped/oss/blob/main/.github/workflows/triage.yml + sha = 33000c0c4ab4eb4e0e142fa54515b811a189d55c + etag = 013a47739e348f06891f37c45164478cca149854e6cd5c5158e6f073f852b61a weak diff --git a/Directory.Build.rsp b/Directory.Build.rsp index 7c0dbc1..509cc66 100644 --- a/Directory.Build.rsp +++ b/Directory.Build.rsp @@ -2,4 +2,4 @@ -nr:false -m:1 -v:m --clp:Summary;ForceNoAlign \ No newline at end of file +-clp:Summary;ForceNoAlign diff --git a/_config.yml b/_config.yml index a61f7e0..04e6093 100644 --- a/_config.yml +++ b/_config.yml @@ -1,3 +1,3 @@ theme: jekyll-theme-slate -exclude: [ 'src/', '*.sln', 'Gemfile*', '*.rsp' ] \ No newline at end of file +exclude: [ 'src/', '*.sln', '*.slnx', 'Gemfile*', '*.rsp' ] diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 028c354..29281ee 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,4 +1,4 @@ - + @@ -20,16 +20,17 @@ Daniel Cazzulino + Devlooped Copyright (C) Daniel Cazzulino and Contributors. All rights reserved. false MIT icon.png - readme.md + readme.md icon.png - readme.md + readme.md true true @@ -37,16 +38,19 @@ $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\bin')) - true + true + true true + + false + + true Release - true - false Latest @@ -112,11 +116,13 @@ after the fixed prefix. This allows dogfooding a branch build. The suffix is sanitized and optionally turned into --> - 42.42.42 + 42.42.42 <_VersionLabel>$(VersionLabel.Replace('refs/heads/', '')) + <_VersionLabel>$(_VersionLabel.Replace('refs/tags/v', '')) + <_VersionLabel Condition="$(_VersionLabel.Contains('refs/pull/'))">$(VersionLabel.TrimEnd('.0123456789')) @@ -125,9 +131,22 @@ <_VersionLabel>$(_VersionLabel.Replace('/merge', '')) <_VersionLabel>$(_VersionLabel.Replace('/', '-')) + + <_VersionLabel>$(_VersionLabel.Replace('_', '-')) - $(_VersionLabel) + $(_VersionLabel) + + $(_VersionLabel) + + + true + 42.42.0 + $(VersionSuffix).$(GITHUB_RUN_NUMBER) @@ -141,5 +160,28 @@ + + + + + + + + + + + 1.0.0 + $(VersionPrefix)-$(VersionSuffix) + $(VersionPrefix) + + + + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 11b776b..083afa6 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -4,6 +4,13 @@ CI;$(DefineConstants) + + + + false + false + true + true @@ -27,24 +34,29 @@ + + CopyToOutputDirectory="Never" + Condition="'$(PackReadme)' != 'false' and '$(PackageReadmeFile)' != ''" /> + CopyToOutputDirectory="Never" + Condition="Exists('$(MSBuildThisFileDirectory)icon.png') and !Exists('$(MSBuildProjectDirectory)\icon.png')" /> + CopyToOutputDirectory="Never" + Condition="'$(PackReadme)' != 'false' and Exists('$(MSBuildThisFileDirectory)readme.md') and !Exists('$(MSBuildProjectDirectory)\readme.md')" /> + CoreResGen;$(CoreCompileDependsOn) + + - - - + + + + + $(IntermediateOutputPath)\$([MSBuild]::ValueOrDefault('%(RelativeDir)', '').Replace('\', '.').Replace('/', '.'))%(Filename).g$(DefaultLanguageSourceExtension) + $(Language) + $(RootNamespace) + $(RootNamespace).$([MSBuild]::ValueOrDefault('%(RelativeDir)', '').Replace('\', '.').Replace('/', '.').TrimEnd('.')) + %(Filename) + @@ -141,6 +165,9 @@ @(_GitSourceRoot) + + $([System.IO.Path]::GetFileNameWithoutExtension($(PrivateRepositoryUrl))) + $(ProductFromUrl) @@ -151,13 +178,14 @@ Condition="'$(SourceControlInformationFeatureSupported)' == 'true' And '$(IsPackable)' == 'true'"> - $(RepositoryUrl) + $(RepositoryUrl.Replace('.git', '')) $(Description) - $(RepositoryUrl)/blob/main/changelog.md + $(RepositoryUrl.Replace('.git', ''))/blob/main/changelog.md +