Create draft release with prepared assets #23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Create draft release with prepared assets | |
| on: | |
| workflow_dispatch: | |
| jobs: | |
| build_and_release: | |
| name: Build and release | |
| runs-on: windows-latest | |
| permissions: | |
| contents: write | |
| env: | |
| NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Generate release version | |
| id: version | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| shell: bash | |
| run: | | |
| today=$(date +'%Y.%m.%d') | |
| default_version="v${today}.0" | |
| # fetch the latest release tag name | |
| latest_version=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' || echo "") | |
| # check if we successfully got a latest version and if its date matches today's date | |
| if [ -n "$latest_version" ] && [[ "$latest_version" =~ ^v([0-9]{4}\.[0-9]{2}\.[0-9]{2})\.([0-9]+)$ ]]; then | |
| latest_date="${BASH_REMATCH[1]}" | |
| latest_increment="${BASH_REMATCH[2]}" | |
| if [ "$latest_date" == "$today" ]; then | |
| # date matches; increment the number | |
| new_increment=$(($latest_increment + 1)) | |
| new_version="v${today}.${new_increment}" | |
| else | |
| # date does not match; use the default version with .0 | |
| new_version="$default_version" | |
| fi | |
| else | |
| # No latest release found or format is unexpected, use the default version with .0 | |
| new_version="$default_version" | |
| fi | |
| echo "Using version $new_version" | |
| echo "version=$new_version" >> $GITHUB_OUTPUT | |
| - name: Clean version string | |
| id: clean_version | |
| shell: bash | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| # remove 'v' prefix | |
| VERSION=${VERSION#v} | |
| # split by '.' and remove leading zeros from each part | |
| IFS='.' read -ra ADDR <<< "$VERSION" | |
| CLEAN_VERSION="" | |
| for i in "${ADDR[@]}"; do | |
| # remove leading zeros unless it's a single zero | |
| CLEAN_VERSION+="$(echo "$i" | sed 's/^0\([0-9]\)/\1/g')." | |
| done | |
| CLEAN_VERSION=${CLEAN_VERSION%.} # remove trailing dot | |
| echo "clean_version=$CLEAN_VERSION" >> $GITHUB_OUTPUT | |
| echo "Setting FileVersion to $CLEAN_VERSION" | |
| - name: "Update .csproj FileVersion" | |
| if: success() | |
| shell: bash | |
| run: | | |
| CLEAN_VERSION="${{ steps.clean_version.outputs.clean_version }}" | |
| CSPROJ_FILES=( | |
| "dotnet/RAWebServer/RAWebServer.csproj" | |
| "dotnet/RAWeb.Server.Utilities/RAWeb.Server.Utilities.csproj" | |
| "dotnet/RAWeb.Server.Management/RAWeb.Server.Management.csproj" | |
| "dotnet/RAWeb.Server.Management.ServiceHost/RAWeb.Server.Management.ServiceHost.csproj" | |
| ) | |
| # loop through each file path | |
| for CSPROJ_FILE in "${CSPROJ_FILES[@]}"; do | |
| echo "Updating FileVersion in $CSPROJ_FILE to $CLEAN_VERSION" | |
| sed -i'' -E "s|(<FileVersion>)[0-9\.]+(</FileVersion>)|\1$CLEAN_VERSION\2|g" "$CSPROJ_FILE" | |
| # check if the sed command actually modified the file | |
| if [ $? -ne 0 ]; then | |
| echo "Warning: Failed to update or find <FileVersion> tag in $CSPROJ_FILE." | |
| fi | |
| done | |
| - name: Move repository setup.ps1 to dotnet/RAWebServer so it is included in the release archive | |
| shell: bash | |
| run: | | |
| mv setup.ps1 dotnet/RAWebServer/setup.ps1 | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10.11 | |
| run_install: false | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22.15.0" | |
| cache: "pnpm" | |
| cache-dependency-path: frontend/pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: cd frontend && pnpm install | |
| - name: Build the frontend (no embedded docs) | |
| run: cd frontend && pnpm run build | |
| env: | |
| RAWEB_EXCLUDE_DOCS: true | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: "8.0.x" | |
| cache: false | |
| - name: Restore .NET solution | |
| run: dotnet restore RAWeb.sln --locked-mode | |
| - name: Build .NET solution | |
| run: dotnet build RAWeb.sln --configuration Release --no-restore | |
| - name: Replace App_Code and bin directories with build output | |
| shell: bash | |
| run: | | |
| rm -rf dotnet/RAWebServer/App_Code | |
| rm -rf dotnet/RAWebServer/src | |
| rm -rf dotnet/RAWebServer/ext | |
| rm -rf dotnet/RAWebServer/obj | |
| rm -rf dotnet/RAWebServer/bin | |
| rm -rf dotnet/RAWebServer/RAWebServer.csproj | |
| rm -rf dotnet/RAWebServer/packages.lock.json | |
| rm -rf dotnet/RAWebServer/.gitignore | |
| rm -rf dotnet/RAWebServer/.vscode | |
| cp -r dotnet/RAWebServer/build/bin dotnet/RAWebServer/bin | |
| rm -rf dotnet/RAWebServer/build | |
| - name: Generate archive (no embedded docs) | |
| uses: thedoctor0/[email protected] | |
| with: | |
| type: "zip" | |
| directory: dotnet/RAWebServer/ | |
| filename: "../../raweb_${{ steps.version.outputs.version }}__no_docs.zip" | |
| - name: Build the frontend | |
| run: cd frontend && pnpm run build | |
| - name: Generate archive | |
| uses: thedoctor0/[email protected] | |
| with: | |
| type: "zip" | |
| directory: dotnet/RAWebServer/ | |
| filename: "../../raweb_${{ steps.version.outputs.version }}.zip" | |
| - name: Write release install.ps1 | |
| shell: bash | |
| run: | | |
| cat <<EOF > "install.ps1" | |
| [CmdletBinding()] | |
| Param( | |
| [switch]\$AcceptAll | |
| ) | |
| \$ProgressPreference = 'SilentlyContinue' | |
| function New-TemporaryDirectory { | |
| \$tmp = [System.IO.Path]::GetTempPath() | |
| \$name = (New-Guid).ToString("N") | |
| New-Item -ItemType Directory -Path (Join-Path \$tmp \$name) | |
| } | |
| # create a temporary directory and do everything there | |
| Set-Location (New-TemporaryDirectory) | |
| # download the built version of RAWeb and extract to dotnet\RAWebServer (expected by the respository's install.ps1) | |
| \$zipUrl = "https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/raweb_${{ steps.version.outputs.version }}.zip" | |
| \$zipPath = Join-Path \$pwd "raweb_${{ steps.version.outputs.version }}.zip" | |
| \$extractPath = Join-Path \$pwd "dotnet\RAWebServer" | |
| Write-Host Downloading... | |
| Write-Verbose "Downloading \$zipUrl to \$zipPath" | |
| Invoke-WebRequest -Uri \$zipUrl -OutFile \$zipPath | |
| Write-Host Extracting... | |
| Write-Verbose "Extracting \$zipPath to \$extractPath" | |
| Expand-Archive -Path \$zipPath -DestinationPath \$extractPath -Force | |
| Write-Verbose "Removing \$zipPath" | |
| Remove-Item -Path \$zipPath | |
| Write-Host Starting... | |
| # move setup.ps1 to the current directory | |
| \$setupPath = Join-Path \$extractPath "setup.ps1" | |
| Write-Verbose "Moving \$setupPath to \$pwd" | |
| Move-Item -Path \$setupPath -Destination (Join-Path \$pwd "setup.ps1") | |
| # make an empty frontend dir so setup.ps1 does quit due to it | |
| # not being available (it will not be used; the frontend is already built) | |
| \$frontendDirPath = Join-Path \$pwd "frontend" | |
| Write-Verbose "Creating empty directory \$frontendDirPath" | |
| New-Item -ItemType Directory -Force -Path \$frontendDirPath | Out-Null | |
| # run setup.ps1 | |
| Write-Verbose "Running setup.ps1 using powershell.exe" | |
| if (\$AcceptAll) { | |
| Write-Verbose "Accepting all prompts" | |
| \$setupCommand = '.\setup.ps1 -AcceptAll' | |
| } else { | |
| \$setupCommand = '.\setup.ps1' | |
| } | |
| powershell.exe -NoProfile -ExecutionPolicy Bypass -Command \$setupCommand | |
| # clean up | |
| \$loc = \$pwd | |
| Write-Verbose "Removing \$loc" | |
| Set-Location ~ | |
| Remove-Item -Path \$loc -Recurse -Force | |
| EOF | |
| - name: Create draft release | |
| uses: ncipollo/release-action@v1 | |
| with: | |
| artifacts: "raweb_${{ steps.version.outputs.version }}.zip,raweb_${{ steps.version.outputs.version }}__no_docs.zip,install.ps1" # comma-delimited list of artifact names | |
| tag: "${{ steps.version.outputs.version }}" | |
| name: "Release ${{ steps.version.outputs.version }}" | |
| draft: true | |
| generateReleaseNotes: true | |
| skipIfReleaseExists: true | |
| body: | | |
| ## Install this release | |
| 1. **Open PowerShell as an administrator** | |
| Press the Windows key + X, then select PowerShell (Administrator) or Terminal (Administrator). | |
| 2. **Copy and paste the code below, then press enter.** | |
| ``` | |
| irm https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/install.ps1 | iex | |
| ``` | |
| 3. Follow the prompts. | |
| > [!IMPORTANT] | |
| > The installer will retrieve `raweb_${{ steps.version.outputs.version }}.zip` from the release and install it to `C:\inetpub\RAWeb`. | |
| > Refer to the [wiki](https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/docs) for more details. | |
| > [!NOTE] | |
| > If Internet Information Services (IIS) or other required components are not already installed, the RAWeb installer will retreive and install them. | |
| <details> | |
| <summary>Advanced installation</summary> | |
| ### Non-interactive installation | |
| To install without prompts, use the following command instead: | |
| ``` | |
| & ([scriptblock]::Create((irm https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/install.ps1))) -AcceptAll | |
| ``` | |
| If RAWeb is already installed, **installing with this option will replace the existing installed files.** Resources, policies, and other data in `/App_Data` with be preserved. | |
| ### Verbose installation | |
| To show verbose logs, use the following command instead: | |
| ``` | |
| & ([scriptblock]::Create((irm https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/install.ps1))) -Verbose -Debug | |
| ``` | |
| </details> | |
| <br/> |