From 911c32439946c8e1561c4e38be8b060424453582 Mon Sep 17 00:00:00 2001 From: "Calvin A. Allen" Date: Wed, 31 Dec 2025 11:00:31 -0500 Subject: [PATCH 1/2] ci: add release workflow with store and social notifications - Trigger on v* tag push - Build portable and MSIX packages for x64, x86, arm64 - Generate changelog using reusable workflow - Create GitHub release with artifacts - Submit to Microsoft Store (non-prereleases) - Post notifications to Bluesky and LinkedIn --- .github/workflows/release.yml | 195 ++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..825f6ce --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,195 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + actions: read + +env: + PROJECT_PATH: src/CodingWithCalvin.VSToolbox/CodingWithCalvin.VSToolbox.csproj + APP_NAME: VSToolbox + +jobs: + changelog: + name: Generate Changelog + uses: CodingWithCalvin/.github/.github/workflows/generate-changelog.yml@main + secrets: inherit + + build: + runs-on: windows-latest + + strategy: + matrix: + platform: [x64, x86, arm64] + + outputs: + version: ${{ steps.version.outputs.VERSION }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + - name: Get version from tag + id: version + shell: pwsh + run: | + $tag = "${{ github.ref_name }}" + $version = $tag -replace '^v', '' + echo "VERSION=$version" >> $env:GITHUB_OUTPUT + echo "Version: $version" + + - name: Update version in manifest + shell: pwsh + run: | + $manifest = "src/CodingWithCalvin.VSToolbox/Package.appxmanifest" + $content = Get-Content $manifest -Raw + $content = $content -replace 'Version="[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"', "Version=`"${{ steps.version.outputs.VERSION }}.0`"" + Set-Content $manifest $content + + - name: Restore dependencies + run: dotnet restore ${{ env.PROJECT_PATH }} + + # Build portable (self-contained) executable + - name: Build portable + run: | + dotnet publish ${{ env.PROJECT_PATH }} ` + --configuration Release ` + --runtime win-${{ matrix.platform }} ` + --self-contained true ` + -p:PublishSingleFile=false ` + -p:PublishReadyToRun=true ` + -p:PublishTrimmed=true ` + -p:Platform=${{ matrix.platform }} ` + --output ./artifacts/portable/${{ matrix.platform }} + + - name: Zip portable build + shell: pwsh + run: | + Compress-Archive -Path ./artifacts/portable/${{ matrix.platform }}/* -DestinationPath ./artifacts/${{ env.APP_NAME }}-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}-portable.zip + + # Build MSIX package + - name: Build MSIX + run: | + dotnet publish ${{ env.PROJECT_PATH }} ` + --configuration Release ` + --runtime win-${{ matrix.platform }} ` + -p:Platform=${{ matrix.platform }} ` + -p:WindowsPackageType=MSIX ` + -p:AppxPackageDir=./artifacts/msix/${{ matrix.platform }}/ ` + -p:AppxBundle=Never ` + -p:UapAppxPackageBuildMode=SideloadOnly ` + -p:GenerateAppxPackageOnBuild=true + + - name: Find and rename MSIX + shell: pwsh + run: | + $msix = Get-ChildItem -Path ./artifacts/msix/${{ matrix.platform }} -Filter *.msix -Recurse | Select-Object -First 1 + if ($msix) { + Copy-Item $msix.FullName "./artifacts/${{ env.APP_NAME }}-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}.msix" + } + + - name: Upload portable artifact + uses: actions/upload-artifact@v4 + with: + name: portable-${{ matrix.platform }} + path: ./artifacts/${{ env.APP_NAME }}-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}-portable.zip + + - name: Upload MSIX artifact + uses: actions/upload-artifact@v4 + with: + name: msix-${{ matrix.platform }} + path: ./artifacts/${{ env.APP_NAME }}-${{ steps.version.outputs.VERSION }}-${{ matrix.platform }}.msix + if-no-files-found: warn + + release: + needs: [changelog, build] + runs-on: ubuntu-latest + outputs: + version: ${{ needs.build.outputs.version }} + + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + merge-multiple: true + + - name: List artifacts + run: ls -la artifacts/ + + - name: Create GitHub Release + uses: ncipollo/release-action@v1.14.0 + with: + artifacts: artifacts/* + body: ${{ needs.changelog.outputs.changelog }} + makeLatest: true + tag: ${{ github.ref_name }} + prerelease: ${{ contains(github.ref_name, '-') }} + + store: + needs: [build, release] + runs-on: windows-latest + if: ${{ !contains(github.ref_name, '-') }} # Skip for pre-releases + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download MSIX artifacts + uses: actions/download-artifact@v4 + with: + pattern: msix-* + path: msix-packages + merge-multiple: true + + - name: List MSIX packages + shell: pwsh + run: Get-ChildItem -Path msix-packages -Recurse + + - name: Submit to Microsoft Store + uses: microsoft/store-submission@v1 + with: + command: publish + productId: ${{ secrets.STORE_PRODUCT_ID }} + tenantId: ${{ secrets.AZURE_TENANT_ID }} + clientId: ${{ secrets.AZURE_CLIENT_ID }} + clientSecret: ${{ secrets.AZURE_CLIENT_SECRET }} + packagePath: msix-packages/ + + notify-bluesky: + needs: [release, store] + if: ${{ !contains(github.ref_name, '-') }} + uses: CodingWithCalvin/.github/.github/workflows/bluesky-post.yml@main + with: + post_text: | + 🚀 VSToolbox v${{ needs.release.outputs.version }} has been released! + + [Check out the release notes here!](https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}) + + Get it from the Microsoft Store or download directly from GitHub! + secrets: + BLUESKY_USERNAME: ${{ secrets.BLUESKY_USERNAME }} + BLUESKY_APP_PASSWORD: ${{ secrets.BLUESKY_APP_PASSWORD }} + + notify-linkedin: + needs: [release, store] + if: ${{ !contains(github.ref_name, '-') }} + uses: CodingWithCalvin/.github/.github/workflows/linkedin-post.yml@main + with: + post_text: | + 🚀 VSToolbox v${{ needs.release.outputs.version }} has been released! + + Check out the release notes here: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }} + + Get it from the Microsoft Store or download directly from GitHub! + secrets: + LINKEDIN_ACCESS_TOKEN: ${{ secrets.LINKEDIN_ACCESS_TOKEN }} From 92ee25d7b87a5f7fae2a8a221b5fdd1b4e7e183b Mon Sep 17 00:00:00 2001 From: "Calvin A. Allen" Date: Wed, 31 Dec 2025 12:01:13 -0500 Subject: [PATCH 2/2] ci: temporarily disable Microsoft Store submission Store submission will be enabled once the required secrets are configured. --- .github/workflows/release.yml | 67 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 825f6ce..a3017a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -135,38 +135,39 @@ jobs: tag: ${{ github.ref_name }} prerelease: ${{ contains(github.ref_name, '-') }} - store: - needs: [build, release] - runs-on: windows-latest - if: ${{ !contains(github.ref_name, '-') }} # Skip for pre-releases - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Download MSIX artifacts - uses: actions/download-artifact@v4 - with: - pattern: msix-* - path: msix-packages - merge-multiple: true - - - name: List MSIX packages - shell: pwsh - run: Get-ChildItem -Path msix-packages -Recurse - - - name: Submit to Microsoft Store - uses: microsoft/store-submission@v1 - with: - command: publish - productId: ${{ secrets.STORE_PRODUCT_ID }} - tenantId: ${{ secrets.AZURE_TENANT_ID }} - clientId: ${{ secrets.AZURE_CLIENT_ID }} - clientSecret: ${{ secrets.AZURE_CLIENT_SECRET }} - packagePath: msix-packages/ + # TODO: Enable Microsoft Store submission once secrets are configured + # store: + # needs: [build, release] + # runs-on: windows-latest + # if: ${{ !contains(github.ref_name, '-') }} # Skip for pre-releases + # + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # + # - name: Download MSIX artifacts + # uses: actions/download-artifact@v4 + # with: + # pattern: msix-* + # path: msix-packages + # merge-multiple: true + # + # - name: List MSIX packages + # shell: pwsh + # run: Get-ChildItem -Path msix-packages -Recurse + # + # - name: Submit to Microsoft Store + # uses: microsoft/store-submission@v1 + # with: + # command: publish + # productId: ${{ secrets.STORE_PRODUCT_ID }} + # tenantId: ${{ secrets.AZURE_TENANT_ID }} + # clientId: ${{ secrets.AZURE_CLIENT_ID }} + # clientSecret: ${{ secrets.AZURE_CLIENT_SECRET }} + # packagePath: msix-packages/ notify-bluesky: - needs: [release, store] + needs: [release] if: ${{ !contains(github.ref_name, '-') }} uses: CodingWithCalvin/.github/.github/workflows/bluesky-post.yml@main with: @@ -174,14 +175,12 @@ jobs: 🚀 VSToolbox v${{ needs.release.outputs.version }} has been released! [Check out the release notes here!](https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}) - - Get it from the Microsoft Store or download directly from GitHub! secrets: BLUESKY_USERNAME: ${{ secrets.BLUESKY_USERNAME }} BLUESKY_APP_PASSWORD: ${{ secrets.BLUESKY_APP_PASSWORD }} notify-linkedin: - needs: [release, store] + needs: [release] if: ${{ !contains(github.ref_name, '-') }} uses: CodingWithCalvin/.github/.github/workflows/linkedin-post.yml@main with: @@ -189,7 +188,5 @@ jobs: 🚀 VSToolbox v${{ needs.release.outputs.version }} has been released! Check out the release notes here: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }} - - Get it from the Microsoft Store or download directly from GitHub! secrets: LINKEDIN_ACCESS_TOKEN: ${{ secrets.LINKEDIN_ACCESS_TOKEN }}