diff --git a/.github/workflows/azureartifact.yml b/.github/workflows/azureartifact.yml new file mode 100644 index 0000000..961eaae --- /dev/null +++ b/.github/workflows/azureartifact.yml @@ -0,0 +1,82 @@ +name: Publish Universal Package + +on: + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Restore dependencies + run: dotnet restore CircleApp.sln + + - name: Build + run: dotnet build CircleApp/CircleApp.csproj --configuration Release --no-restore + + - name: Publish project + run: dotnet publish CircleApp/CircleApp.csproj --configuration Release --output ./publish + + - name: Create deployment zip + run: | + cd ./publish + zip -r ../CircleApp.zip . + cd .. + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: CircleAppPackage + path: CircleApp.zip + + # Install Azure CLI + DevOps extension + - name: Install Azure CLI + run: | + sudo apt-get update + sudo apt-get install -y azure-cli + az extension add --name azure-devops + + - name: Azure DevOps Login + env: + AZURE_DEVOPS_EXT_PAT: ${{ secrets.AZURE_DEVOPS_PAT }} + run: | + echo "$AZURE_DEVOPS_EXT_PAT" | az devops login --organization "https://dev.azure.com/practice990/" + + # required for ArtifactTool + export AZURE_DEVOPS_EXT_ARTIFACTTOOL_PATVAR=$AZURE_DEVOPS_EXT_PAT + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: CircleAppPackage + path: CircleAppPackage + + # Prepare folder for upload + # Universal Packages require a FOLDER, not a .zip file directly + - name: Prepare artifact folder + run: | + mkdir -p upload_folder + cp ./CircleApp.zip upload_folder/ + + - name: Publish Universal Package + env: + AZURE_DEVOPS_EXT_PAT: ${{ secrets.AZURE_DEVOPS_PAT }} + run: | + export AZURE_DEVOPS_EXT_ARTIFACTTOOL_PATVAR=$AZURE_DEVOPS_EXT_PAT + + az artifacts universal publish \ + --organization "https://dev.azure.com/practice990/" \ + --project "test123" \ + --scope project \ + --feed "artifacts" \ + --name "CircleApp" \ + --version "1.0.0" \ + --path "upload_folder" diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml new file mode 100644 index 0000000..f193236 --- /dev/null +++ b/.github/workflows/github.yml @@ -0,0 +1,187 @@ +name: github teting + +on: + workflow_dispatch: + # pull_request: + # types: [opened, synchronize, reopened, closed] + # push: + # branches: + # - master + # - develop + # - release + +env: + # AZURE_WEBAPP_NAME: "app-munson-api-eastus-dev-001" + ArtifactName: "TEST" + +permissions: + contents: read + pages: write + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Restore dependencies + run: dotnet restore CircleApp.sln + + - name: Build + run: dotnet build CircleApp/CircleApp.csproj --configuration Release --no-restore + + - name: Publish project + run: dotnet publish CircleApp/CircleApp.csproj --configuration Release --output ./publish + + - name: Create deployment zip + run: | + cd ./publish + zip -r ../CircleApp.zip . + cd .. + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: CircleAppPackage + path: CircleApp.zip + + deployOnDev: + runs-on: runner1 + needs: build + # if: github.base_ref == 'master' + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: CircleAppPackage + path: CircleAppPackage + + - name: Install Azure CLI + run: | + curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + + - name: Login to Azure Subscription + uses: azure/login@v1 + with: + client-id: ${{ secrets.DEV_AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + allow-no-subscriptions: true + + # 3. Upload artifact into VM's C:\temp + - name: Upload artifact to VM + run: | + az vm run-command invoke \ + --resource-group testvm_group \ + --name testvm \ + --command-id RunPowerShellScript \ + --scripts "New-Item -Path 'C:\\temp\\' -ItemType Directory -Force" + # 3. Upload artifact into VM's C:\temp + - name: Upload artifact to VM + run: | + # First, copy the artifact to a location accessible by the VM + # Since we're on a self-hosted runner, we can access the workspace directly + + # Create temp directory on VM + az vm run-command invoke \ + --resource-group testvm_group \ + --name testvm \ + --command-id RunPowerShellScript \ + --scripts "New-Item -Path 'C:\\temp\\' -ItemType Directory -Force" + + # Remove old artifact if exists + az vm run-command invoke \ + --resource-group testvm_group \ + --name testvm \ + --command-id RunPowerShellScript \ + --scripts "Remove-Item -Path 'C:\\temp\\CircleApp.zip' -Force -ErrorAction SilentlyContinue" + + # Copy the artifact from the GitHub runner to the VM using Azure file copy + # Note: This requires the VM to have proper network access and the service principal to have Storage permissions + az vm run-command invoke \ + --resource-group testvm_group \ + --name testvm \ + --command-id RunPowerShellScript \ + --scripts "Copy-Item 'CircleAppPackage/CircleApp.zip' -Destination 'C:\\temp\\'" + + # - name: Set up SSH key + # run: | + # mkdir -p ~/.ssh + # echo "${{ secrets.IIS_SSH_KEY }}" > ~/.ssh/id_rsa + # chmod 600 ~/.ssh/id_rsa + # ssh-keyscan -H ${{ secrets.IIS_SSH_HOST }} >> ~/.ssh/known_hosts + + # - name: Copy files to IIS server over SSH + # run: | + # scp -i ~/.ssh/id_rsa CircleAppPackage/CircleApp.zip sam@20.245.242.103:"C:/temp/" + + # - name: Deploy on IIS using PowerShell over SSH + # run: | + # ssh -i ~/.ssh/id_rsa ${{ secrets.IIS_SSH_USER }}@${{ secrets.IIS_SSH_HOST }} 'powershell -Command " + # Expand-Archive -Path C:/Temp/CircleApp.zip -DestinationPath C:/inetpub/wwwroot/CircleApp -Force; + # iisreset + # # Restart-WebAppPool -Name \"DefaultAppPool\" + # " + +################################################################################ + + # - name: Setup Python and Install WinRM client + # run: | + # python3 -m pip install --upgrade pip + # pip3 install pywinrm requests-ntlm + + # - name: Deploy via WinRM + # run: | + # python3 - <<'EOF' + # import os, winrm, base64 + + # # --- Config --- + # win_host = "${{ secrets.IIS_HOST }}" # IIS public IP or DNS + # win_user = "${{ secrets.IIS_USER }}" # Windows user + # win_pass = "${{ secrets.IIS_PASSWORD }}" # Windows password + # local_folder = "CircleAppPackage/CircleApp.zip" # Build output folder on runner + # remote_temp = "C:\\temp\\" # Temp staging folder on IIS + # remote_wwwroot = "C:\\inetpub\\wwwroot\\CircleApp" + + # # --- Connect to WinRM --- + # session = winrm.Session( + # f'http://{win_host}:5985/wsman', + # auth=(win_user, win_pass), + # transport='ntlm' # Use NTLM for Windows domain/local accounts + # ) + + # # --- Ensure temp folder exists --- + # session.run_ps(f"New-Item -Path {remote_temp} -ItemType Directory -Force") + + # # --- Upload files one by one --- + # for root, dirs, files in os.walk(local_folder): + # for file in files: + # local_path = os.path.join(root, file) + # rel_path = os.path.relpath(local_path, local_folder) + # remote_path = os.path.join(remote_temp, rel_path).replace("/", "\\") + # remote_dir = os.path.dirname(remote_path) + + # # ensure remote dir exists + # session.run_ps(f"New-Item -Path '{remote_dir}' -ItemType Directory -Force") + + # # upload file content (base64 encode to avoid corruption) + # with open(local_path, "rb") as f: + # content = base64.b64encode(f.read()).decode("utf-8") + # ps_script = f""" + # $bytes = [System.Convert]::FromBase64String("{content}") + # [System.IO.File]::WriteAllBytes("{remote_path}", $bytes) + # """ + # session.run_ps(ps_script) + + # # --- Move to IIS wwwroot --- + # session.run_ps(f"Copy-Item {remote_temp}\\* {remote_wwwroot} -Recurse -Force") + + # # --- Restart IIS --- + # r = session.run_ps("iisreset") + # print(r.std_out.decode(), r.std_err.decode()) + # EOF diff --git a/.github/workflows/linuxtest.yml b/.github/workflows/linuxtest.yml new file mode 100644 index 0000000..f92b2c3 --- /dev/null +++ b/.github/workflows/linuxtest.yml @@ -0,0 +1,194 @@ +name: linux testing + +on: + workflow_dispatch: + # pull_request: + # types: [opened, synchronize, reopened, closed] + # push: + # branches: + # - master + # - develop + # - release + +env: + # AZURE_WEBAPP_NAME: "app-munson-api-eastus-dev-001" + ArtifactName: "TEST" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Restore dependencies + run: dotnet restore CircleApp.sln + + - name: Build + run: dotnet build CircleApp/CircleApp.csproj --configuration Release --no-restore + + - name: Publish project + run: dotnet publish CircleApp/CircleApp.csproj --configuration Release --output ./publish + + - name: Create deployment zip + run: | + cd ./publish + zip -r ../CircleApp.zip . + cd .. + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: CircleAppPackage + path: CircleApp.zip + + deployOnDev: + runs-on: ubuntu-latest + needs: build + # if: github.base_ref == 'master' + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: CircleAppPackage + path: CircleAppPackage + + # - name: Copy files to remote server via SCP + # env: + # SSH_KEY: p@ssword@123 + # run: | + # # Install sshpass if you want to use password (not recommended) + # sudo apt-get update && sudo apt-get install -y sshpass + + - name: Install PowerShell + run: | + # Update package list + sudo apt-get update + + # Install pre-requisites + sudo apt-get install -y wget apt-transport-https software-properties-common + + # Download Microsoft repository GPG keys + wget -q "https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb" -O packages-microsoft-prod.deb + + # Register Microsoft repository + sudo dpkg -i packages-microsoft-prod.deb + + # Update after adding repo + sudo apt-get update + + # Install PowerShell + sudo apt-get install -y powershell + + # Start PowerShell + pwsh + - name: Copy artifact to Windows Server + run: | + sudo apt-get update + sudo apt-get install -y sshpass + sshpass -p '${{ secrets.IIS_PASSWORD }}' \ + scp -o StrictHostKeyChecking=no CircleAppPackage/CircleApp.zip \ + sam@52.225.18.246:/C:/temp/ + # ${{ secrets.IIS_USER }}@${{ secrets.IIS_SERVER }}:C:/Temp/ + # sshpass -p ${{ secrets.IIS_PASSWORD }} \ + # ssh -o StrictHostKeyChecking=no sam@20.245.242.103 powershell -Command ' + # iisreset /stop; + # Expand-Archive -Path C:\temp\CircleApp.zip -DestinationPath C:\inetpub\wwwroot\CircleApp -Force; + # iisreset /start + # ' + - name: Unzip on IIS via SSH + # env: + # IIS_USERNAME: "sam" + # IIS_PASSWORD: "p@ssword@123" + # IIS_HOST: "20.245.242.103" + # IIS_TARGET_PATH: C:\inetpub\wwwroot\CircleApp + run: | + # sshpass -p "$IIS_PASSWORD" ssh -o StrictHostKeyChecking=no "$IIS_USERNAME@$IIS_HOST" powershell -Command "Expand-Archive -Path 'C:\temp\CircleApp.zip' -DestinationPath '$env:IIS_TARGET_PATH' -Force" + # sshpass -p "p@ssword@123" ssh -o StrictHostKeyChecking=no sam@20.245.242.103 'powershell -Command "& ''C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe'' -verb:sync -source:package=''C:\temp\CircleApp.zip'' -dest:auto,computerName='20.245.242.103',userName='sam',password='p@ssword@123',authType=''basic'' -allowUntrusted"' + # sshpass -p "p@ssword@123" ssh -o StrictHostKeyChecking=no "sam@20.245.242.103" \ + # "powershell -Command '& \"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe\" -verb:sync -source:package=\"C:\temp\CircleApp.zip\" -dest:auto,computerName=\"20.245.242.103\",userName=\"sam\",password=\"p@ssword@123\",authType=\"basic\" -allowUntrusted'" + # imp sshpass -p "p@ssword@123" ssh -o StrictHostKeyChecking=no "sam@20.245.242.103" \ + # imp "powershell -Command \"Expand-Archive -Path 'C:\\temp\\CircleApp.zip' -DestinationPath 'C:\inetpub\wwwroot\CircleApp' -Force\"" + # "powershell -Command \"Expand-Archive -Path 'C:\\temp\\CircleApp.zip' -DestinationPath 'C:\\inetpub\\wwwroot\\CircleApp' -Force; Import-Module WebAdministration; Stop-Website -Name 'Default Web Site'; Start-Website -Name 'Default Web Site'\"" + sshpass -p "p@ssword@123" ssh -o StrictHostKeyChecking=no "sam@52.225.18.246" powershell -File "C:\Users\Sam\deploy.ps1" + + # sshpass -p "p@swword@123" ssh -o StrictHostKeyChecking=no "sam@20.245.242.103" \ + # "powershell -Command \"& 'C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe' -verb:sync -source:package='C:\\temp\\CircleApp.zip' -dest:auto,computerName='20.245.242.103',userName='sam',password='p@ssword@123',authType='basic' -allowUntrusted\"" +########################################################################################### + + # - name: Copy artifact to Windows Server + # run: | + # sudo apt-get update + # sudo apt-get install -y sshpass + # sshpass -p '${{ secrets.IIS_PASSWORD }}' \ + # scp -o StrictHostKeyChecking=no CircleAppPackage/CircleApp.zip \ + # sam@20.245.242.103:C:/Temp/ + # # ${{ secrets.IIS_USER }}@${{ secrets.IIS_SERVER }}:C:/Temp/ + + # - name: Run deploy script remotely + # run: | + # pwsh -Command " + # \$session = New-PSSession -HostName 20.245.242.103 -UserName sam -SSHTransport + # Copy-Item ./deploy.ps1 -Destination C:\temp\deploy.ps1 -ToSession \$session -Force + # Invoke-Command -Session \$session -ScriptBlock { pwsh -File C:\temp\deploy.ps1 } + # Remove-PSSession \$session + # " +##################################################################################################################### + + # - name: Deploy in IIS + # shell: pwsh + # run: | + # pwsh -Command " + # \$user = '${{ secrets.IIS_USER }}' + # \$pass = ConvertTo-SecureString '${{ secrets.IIS_PASSWORD }}' -AsPlainText -Force + # \$cred = New-Object System.Management.Automation.PSCredential(\$user, \$pass) + + # # Create SSH-based session + # \$session = New-PSSession -HostName 20.245.242.103 -UserName \$user -SSHTransport + + # # Example: Copy artifact and restart IIS + # Invoke-Command -Session \$session -ScriptBlock { + # Write-Host 'Deploying app to IIS...' + # # Stop app pool + # Stop-WebAppPool -Name 'DefaultAppPool' + # # Deploy files (you could use robocopy, unzip, etc.) + # Expand-Archive -Path C:\Temp\CircleApp.zip -DestinationPath C:\inetpub\wwwroot\MyApp -Force + # # Restart app pool + # Start-WebAppPool -Name 'DefaultAppPool' + # } + # # Close session + # Remove-PSSession \$session + # " + ###########################################################3 + + # - name: Install tools (if not present in AKS runner image) + # run: | + # sudo apt-get update + # sudo apt-get install -y openssh-client + + # - name: Setup SSH key + # run: | + # mkdir -p ~/.ssh + # echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + # chmod 600 ~/.ssh/id_rsa + # ssh-keyscan -H ${{ secrets.WIN_SERVER }} >> ~/.ssh/known_hosts + + # - name: Copy build artifacts to IIS server + # run: | + # scp -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no -r ./dotnetcorewebapp/* \ + # ${{ secrets.WIN_USER }}@${{ secrets.WIN_SERVER }}:/C:/deploy/dotnetcorewebapp/ + + # - name: Restart IIS and move files + # run: | + # ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no \ + # ${{ secrets.WIN_USER }}@${{ secrets.WIN_SERVER }} powershell -Command " + # iisreset /stop; + # Copy-Item 'C:\deploy\dotnetcorewebapp\*' 'C:\inetpub\wwwroot\dotnetcore-webapp' -Recurse -Force; + # iisreset /start + # " + +############################################################################### diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..f2dae79 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,208 @@ +name: Deploy + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened, closed] + branches: + - master + - develop + - release + +env: + # AZURE_WEBAPP_NAME: "app-munson-api-eastus-dev-001" + ArtifactName: "TEST" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Restore dependencies + run: dotnet restore CircleApp.sln + + - name: Build + run: dotnet build CircleApp/CircleApp.csproj --configuration Release --no-restore + + - name: Publish project + run: dotnet publish CircleApp/CircleApp.csproj --configuration Release --output ./publish + + - name: Create deployment zip + run: | + cd ./publish + zip -r ../CircleApp.zip . + cd .. + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: CircleAppPackage + path: CircleApp.zip + + deployOnDev: + runs-on: dev + needs: build + if: github.base_ref == 'master' + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: CircleAppPackage + path: CircleAppPackage + + + - name: Deploy with Web Deploy imp + shell: powershell + run: | + $msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" + & $msdeploy ` + -verb:sync ` + -source:package="CircleAppPackage/CircleApp.zip" ` + -dest:'contentPath="Default Web Site\CircleApp",computerName="https://52.225.18.246:8172/msdeploy.axd?site=Default Web Site",username="testvm\sam",password="p@ssword@123",authType="Basic"' ` + -allowUntrusted + + +####################################################################### + - name: Auto-delete merged feature branch + if: > + github.event_name == 'pull_request' && + github.event.action == 'closed' && + github.event.pull_request.merged == true && + github.event.pull_request.base.ref == 'master' + run: | + $branch = "${{ github.event.pull_request.head.ref }}" + Write-Host "Branch to delete: $branch" + + if ($branch -ne "master" -and $branch -ne "release" -and $branch -ne "main") { + Write-Host "Deleting branch $branch ..." + $headers = @{ + Authorization = "token ${{ secrets.TOKEN }}" + Accept = "application/vnd.github.v3+json" + } + Invoke-RestMethod -Uri "https://api.github.com/repos/${{ github.repository }}/git/refs/heads/$branch" -Headers $headers -Method Delete + } else { + Write-Host "Skipping deletion of protected branch: $branch" + } + +######################################################################### + + # - name: Deploy with Pass-through Auth + # run: | + # "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync ` + # -source:contentPath="$(Resolve-Path ./CircleAppPackage/CircleApp.zip)" ` + # -dest:contentPath="Default Web Site/CircleApp",computerName="https://52.225.18.246:8172/msdeploy.axd?site=Default Web Site",authType=NTLM -allowUntrusted + +# msdeploy.exe -verb:sync ` +# -source:contentPath="D:\CircleApp" ` +# -dest:contentPath="C:\inetpub\wwwroot\CircleApp" + + # - name: Deploy locally + # shell: powershell + # run: | + # Expand-Archive -Path CircleAppPackage/CircleApp.zip -DestinationPath "C:\inetpub\wwwroot\CircleApp" -Force + # # Restart-WebAppPool -Name "DefaultAppPool" + # $appPool = "DefaultAppPool" + + # # Check current state + # $state = (Get-WebAppPoolState -Name $appPool).Value + + # if ($state -eq "Stopped") { + # Write-Host "App Pool is stopped. Starting..." + # Start-WebAppPool -Name $appPool + # } else { + # Write-Host "App Pool is running. Restarting..." + # Restart-WebAppPool -Name $appPool + # } + # - name: Deploy to IIS + # shell: powershell + # run: | + # $PackagePath = "$(Resolve-Path ./CircleAppPackage/CircleApp.zip)" + # $Server = "20.245.242.103" + # $User = "sam" + # $Pass = "p@ssword@123" + # $Site = "Default Web Site/CircleApp" + # $msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" + + # & "$msdeploy" -verb:sync ` + # -source:package="$PackagePath" ` + # -dest:iisApp="$Site",computerName="https://$Server:8172/msdeploy.axd",userName="$User",password="$Pass",authType="Basic" ` + # -allowUntrusted -enableRule:DoNotDeleteRule + + # - name: Deploy to IIS with MSDeploy + # shell: powershell + # run: | + # $PackagePath = "$(Resolve-Path ./CircleAppPackage/CircleApp.zip)" + # $SiteName = "Default Web Site" + # $AppName = "MercuryHealth" + # $Server = "20.245.242.103" # e.g. 20.245.242.103 + # $Username = "sam" # deployment user + # $Password = "p@ssword@123" # deployment password + # $msdeployPath = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" + + # # Debug info + # Write-Host "Deploying $PackagePath to $Server / $SiteName/$AppName" + + # # Run msdeploy to create/update IIS virtual application + # & "$msdeployPath" -verb:sync ` + # -source:package="$PackagePath" ` + # -dest:iisApp="$SiteName/$AppName",computerName="https://$Server:8172/msdeploy.axd",userName="$Username",password="$Password",authType="Basic" ` + # -allowUntrusted -enableRule:DoNotDeleteRule +############################################################################################### + # - name: Deploy to IIS with msdeploy + # shell: powershell + # run: | + # # Stop on any error + # $ErrorActionPreference = "Stop" + + # # ---------------- Configuration ---------------- + # $SiteName = "Default Web Site" + # $AppPool = "DefaultAppPool" + # $PhysicalPath = "C:\inetpub\wwwroot\CircleApp" + # $PackagePath = "C:\Users\Sam\actions-runner\actions-runner\_work\CircleApp\CircleApp\CircleAppPackage\CircleApp.zip" + # $Server = "20.245.242.103" + # $Username = "sam" + # $Password = "p@ssword@123" + # $msdeployPath = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" + + # Import-Module WebAdministration + + # # ---------------- Check if site exists ---------------- + # $site = Get-Website | Where-Object { $_.Name -eq $SiteName } + + # if (-not $site) { + # Write-Host "Site '$SiteName' does not exist. Creating new site..." + + # # Create app pool if it doesn't exist + # if (-not (Get-WebAppPoolState -Name $AppPool -ErrorAction SilentlyContinue)) { + # New-WebAppPool -Name $AppPool + # Write-Host "App Pool '$AppPool' created." + # } + + # # Create the site + # if (-not (Test-Path $PhysicalPath)) { + # New-Item -ItemType Directory -Path $PhysicalPath -Force + # } + + # New-Website -Name $SiteName -Port 80 -PhysicalPath $PhysicalPath -ApplicationPool $AppPool + # Write-Host "Site '$SiteName' created." + # } else { + # Write-Host "Site '$SiteName' exists. Updating content..." + # } + + # # ---------------- Ensure physical path exists ---------------- + # if (-not (Test-Path $PhysicalPath)) { + # New-Item -ItemType Directory -Path $PhysicalPath -Force + # } + + # # ---------------- Debug Info ---------------- + # $Comp + + + # publish-profile: ${{ secrets.API_PUBLISH_SECRET }} + # package: ./publish diff --git a/.github/workflows/storage.yml b/.github/workflows/storage.yml new file mode 100644 index 0000000..5adcb71 --- /dev/null +++ b/.github/workflows/storage.yml @@ -0,0 +1,143 @@ +name: storage teting + +on: + workflow_dispatch: + # pull_request: + # types: [opened, synchronize, reopened, closed] + # push: + # branches: + # - master + # - develop + # - release + +env: + # AZURE_WEBAPP_NAME: "app-munson-api-eastus-dev-001" + ArtifactName: "TEST" + +permissions: + contents: read + pages: write + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Restore dependencies + run: dotnet restore CircleApp.sln + + - name: Build + run: dotnet build CircleApp/CircleApp.csproj --configuration Release --no-restore + + - name: Publish project + run: dotnet publish CircleApp/CircleApp.csproj --configuration Release --output ./publish + + - name: Create deployment zip + run: | + cd ./publish + zip -r ../CircleApp.zip . + cd .. + # - name: Zip Publish Artifact + # run: | + # mkdir -p ${{ github.workspace }}/CircleApp/Publish + # cd ${{ github.workspace }}/temp/publish + # zip -r ${{ github.workspace }}/CircleApp/Publish/publish.zip . + # # zip -r ../myapp.zip . + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: CircleAppPackage + path: CircleApp.zip + + deployOnDev: + runs-on: runner1 + needs: build + # if: github.base_ref == 'master' + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: CircleAppPackage + path: CircleAppPackage + + - name: Install Azure CLI + run: | + curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + + - name: Login to Azure Subscription + uses: azure/login@v1 + with: + client-id: ${{ secrets.DEV_AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + allow-no-subscriptions: true + + # 3. Upload artifact to Azure Storage so the VM can fetch it + - name: Upload to Azure Storage + run: | + az storage blob upload \ + --account-name testvmgroupb7e2 \ + --container-name artifacts \ + --file CircleAppPackage/CircleApp.zip \ + --name CircleApp_${{ github.run_id }}.zip \ + --overwrite + - name: Deploy to IIS VM + run: | + az vm run-command invoke \ + --resource-group testvm_group \ + --name testvm \ + --command-id RunPowerShellScript \ + --scripts ' + param([string]$RunId) + + $storageAccount = "testvmgroupb7e2" + $container = "artifacts" + $blobName = "CircleApp_$RunId.zip" + $destFile = "C:\temp\CircleApp.zip" + # $destFile = "C:\temp\CircleApp_${{ github.run_id }}.zip" + $destPath = "C:\inetpub\wwwroot\CircleApp" + Write-Output "Authenticating with Managed Identity..." + az login --identity | Out-Null + Write-Output "Downloading file..." + az storage blob download ` + --account-name $storageAccount ` + --container-name $container ` + --name $blobName ` + --file $destFile ` + --auth-mode login + # --overwrite + Write-Output "Download Finished!" + + if (Test-Path $destPath) { Remove-Item -Recurse -Force $destPath } + Expand-Archive -Path $destFile -DestinationPath $destPath -Force + + Import-Module WebAdministration + Restart-WebAppPool "DefaultAppPool" + ' \ + --parameters "RunId=${{ github.run_id }}" + # 7. Trigger IIS Deployment + # - name: Deploy to IIS VM + # run: | + # az vm run-command invoke \ + # --resource-group testvm_group \ + # --name testvm \ + # --command-id RunPowerShellScript \ + # --scripts ./deploy.ps1 \ + # --parameters "RunId=${{ github.run_id }}" + # 4. Deploy into VM (download + extract + restart IIS) + # - name: Deploy on IIS VM + # run: | + # az vm run-command invoke \ + # --resource-group testvm_group \ + # --name testvm \ + # --command-id RunPowerShellScript \ + # --scripts "Invoke-WebRequest -Uri 'https://testvmgroupb7e2.blob.core.windows.net/artifacts/CircleApp.zip' -OutFile 'C:\\temp\\'; Expand-Archive -Path 'C:\\temp\\CircleApp.zip' -DestinationPath 'C:\\inetpub\\wwwroot\\CircleApp' -Force; Import-Module WebAdministration; Restart-WebAppPool -Name 'DefaultAppPool'" + # --command-id RunPowerShellScript \ + # --scripts "Copy-Item 'CircleAppPackage/CircleApp.zip' -Destination 'C:\\deploy\\'" diff --git a/.github/workflows/storagetesting2.yml b/.github/workflows/storagetesting2.yml new file mode 100644 index 0000000..8ed5168 --- /dev/null +++ b/.github/workflows/storagetesting2.yml @@ -0,0 +1,220 @@ +name: full end to end storage teting + +on: + workflow_dispatch: + # pull_request: + # types: [opened, synchronize, reopened, closed] + # push: + # branches: + # - master + # - develop + # - release + +env: + # AZURE_WEBAPP_NAME: "app-munson-api-eastus-dev-001" + ArtifactName: "TEST" + +permissions: + contents: read + pages: write + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Restore dependencies + run: dotnet restore CircleApp.sln + + - name: Build + run: dotnet build CircleApp/CircleApp.csproj --configuration Release --no-restore + + - name: Publish project + run: dotnet publish CircleApp/CircleApp.csproj --configuration Release --output ./publish + + - name: Create deployment zip + run: | + cd ./publish + zip -r ../CircleApp.zip . + cd .. + # - name: Zip Publish Artifact + # run: | + # mkdir -p ${{ github.workspace }}/CircleApp/Publish + # cd ${{ github.workspace }}/temp/publish + # zip -r ${{ github.workspace }}/CircleApp/Publish/publish.zip . + # # zip -r ../myapp.zip . + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: CircleAppPackage + path: CircleApp.zip + + deployOnDev: + runs-on: runner1 + needs: build + # if: github.base_ref == 'master' + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: CircleAppPackage + path: CircleAppPackage + + - name: Install Azure CLI + run: | + curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + + - name: Login to Azure Subscription + uses: azure/login@v1 + with: + client-id: ${{ secrets.DEV_AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + allow-no-subscriptions: true + + # 3. Upload artifact to Azure Storage so the VM can fetch it + + # 3. Upload artifact to Azure Storage so the VM can fetch it + - name: Upload to Azure Storage + run: | + az storage blob upload \ + --account-name testvmgroupb7e2 \ + --container-name artifacts \ + --file CircleAppPackage/CircleApp.zip \ + --name CircleApp_${{ github.run_id }}.zip \ + --overwrite + + - name: Deploy to IIS VM + run: | + az vm run-command invoke \ + --resource-group domain \ + --name dc01 \ + --command-id RunPowerShellScript \ + --scripts ' + param([string]$RunId) + + # Paths & Variables + $storageAccount = "testvmgroupb7e2" + $container = "artifacts" + $blobName = "CircleApp_$RunId.zip" + $destFile = "C:\Temp\CircleApp_$RunId.zip" + $sitePath = "C:\inetpub\wwwroot\CircleApp" + + Write-Output "Authenticating using Managed Identity..." + az login --identity | Out-Null + + # 1️⃣ Download Artifact + Write-Output "Downloading build artifact $blobName..." + az storage blob download ` + --account-name $storageAccount ` + --container-name $container ` + --name $blobName ` + --file $destFile ` + --auth-mode login ` + --overwrite + + Write-Output "Download Completed!" + + # Stop IIS Gracefully + Import-Module WebAdministration + Write-Output "Stopping site & app pool..." + Stop-WebAppPool "DefaultAppPool" + Stop-Website "Default Web Site" + + # Replace Files + Write-Output "Replacing site files..." + if (Test-Path $sitePath) { Remove-Item -Recurse -Force $sitePath } + Expand-Archive -Path $destFile -DestinationPath $sitePath -Force + + # Start IIS + Write-Output "Starting site & app pool..." + Start-WebAppPool "DefaultAppPool" + Start-Website "Default Web Site" + + Write-Output "Deployment completed successfully!" + + # 3️⃣ Delete Artifacts zip file from Blob Storage + Write-Output "Deleting deployment artifact from Blob Storage..." + az storage blob delete ` + --account-name $storageAccount ` + --container-name $container ` + --name $blobName ` + --auth-mode login + + Write-Output "Artifact deleted successfully!" + ' \ + --parameters "RunId=${{ github.run_id }}" + + # - name: Install PowerShell + # run: | + # # Update package list + # sudo apt-get update + + # # Install pre-requisites + # sudo apt-get install -y wget apt-transport-https software-properties-common + + # # Download Microsoft repository GPG keys + # wget -q "https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb" -O packages-microsoft-prod.deb + + # # Register Microsoft repository + # sudo dpkg -i packages-microsoft-prod.deb + + # # Update after adding repo + # sudo apt-get update + + # # Install PowerShell + # sudo apt-get install -y powershell + + # # Start PowerShell + # pwsh + + # - name: Deploy to IIS VM + # run: | + # az vm run-command invoke \ + # --resource-group testvm_group \ + # --name testvm \ + # --command-id RunPowerShellScript \ + # --scripts "@scripts/deploy.ps1" \ + # --parameters "RunId=${{ github.run_id }}" + + + # - name: Deploy to IIS via SSH + # run: | + # sudo apt-get update + # sudo apt-get install -y sshpass + + # pwsh -Command " + # sshpass -p '${{ secrets.WINRM_PASSWORD }}' \ + # ssh -o StrictHostKeyChecking=no ${{ secrets.WINRM_USER }}@${{ secrets.WINRM_HOST }} ` + # 'powershell -File C:\deploy\deploy.ps1'" + # shell: bash + + # - name: Deploy to IIS Server via WinRM + # shell: pwsh + # run: | + # $user = "${{ secrets.WINRM_USERNAME }}" + # $pass = ConvertTo-SecureString "${{ secrets.WINRM_PASSWORD }}" -AsPlainText -Force + # $cred = New-Object System.Management.Automation.PSCredential ($user, $pass) + + # Invoke-Command -ComputerName ${{ secrets.WINRM_HOST }} -Credential $cred -ScriptBlock { + + # $artifactUrl = "${{ secrets.AZURE_STORAGE_SAS_URL }}" + # $downloadPath = "C:\temp\CircleApp_${{ github.run_id }}.zip" + # $webRoot = "C:\inetpub\wwwroot" + + # Write-Host "Downloading artifact from Azure Storage..." + # azcopy copy $artifactUrl $downloadPath --overwrite=true + + # Write-Host "Extracting to IIS folder..." + # Expand-Archive -LiteralPath $downloadPath -DestinationPath $webRoot -Force + + # Write-Host "Restarting IIS..." + # iisreset + # } diff --git a/azurepipeline.yaml b/azurepipeline.yaml new file mode 100644 index 0000000..ccbaa1c --- /dev/null +++ b/azurepipeline.yaml @@ -0,0 +1,91 @@ +trigger: + branches: + include: + - master + +pool: + vmImage: 'windows-latest' # can also use ubuntu-latest if you don’t need msdeploy here + +variables: + buildConfiguration: 'Release' + +stages: +- stage: Build + displayName: "Build and Package CircleApp" + jobs: + - job: BuildJob + displayName: "Restore, Build and Package" + pool: + vmImage: 'ubuntu-latest' + steps: + - task: UseDotNet@2 + displayName: "Install .NET 9 SDK" + inputs: + packageType: 'sdk' + version: '9.0.x' + + # - task: Checkout@1 + + - task: DotNetCoreCLI@2 + displayName: "Restore dependencies" + inputs: + command: 'restore' + projects: 'CircleApp.sln' + + - task: DotNetCoreCLI@2 + displayName: "Publish project" + inputs: + command: 'publish' + projects: 'CircleApp/CircleApp.csproj' + arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/publish' + + - task: ArchiveFiles@2 + displayName: "Create deployment zip" + inputs: + rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/publish' + includeRootFolder: false + archiveType: 'zip' + archiveFile: '$(Build.ArtifactStagingDirectory)/CircleApp.zip' + replaceExistingArchive: true + + - task: PublishBuildArtifacts@1 + displayName: "Publish build artifact" + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/CircleApp.zip' + ArtifactName: 'CircleAppPackage' + publishLocation: 'Container' + +- stage: Deploy + displayName: "Deploy to IIS with MSDeploy" + dependsOn: Build + jobs: + - job: DeployJob + displayName: "MSDeploy to IIS" + pool: + vmImage: 'windows-latest' # Required for msdeploy.exe + steps: + - download: current + artifact: CircleAppPackage + + - powershell: | + Write-Host "Installing Web Deploy if not already installed..." + $url = "https://download.microsoft.com/download/1/2/8/128FEA1C-1F20-4848-BC74-4C4779F83DB5/WebDeploy_amd64_en-US.msi" + $msi = "$env:TEMP\WebDeploy.msi" + Invoke-WebRequest $url -OutFile $msi + Start-Process msiexec.exe -Wait -ArgumentList "/i `"$msi`" /quiet ADDLOCAL=ALL" + displayName: "Install Web Deploy on agent" + + - powershell: | + $msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" + $package = "$(Pipeline.Workspace)\CircleAppPackage\CircleApp.zip" + + & $msdeploy ` + -verb:sync ` + -source:package="$package" ` + -dest:auto,computerName="https://20.245.242.103:8172/msdeploy.axd?site=CircleApp",userName="DeployUser",password="P@ssword@123",authType="Basic" ` + -allowUntrusted + displayName: "Run MSDeploy" + # env: + # IIS_HOST: $(IIS_HOST) + # IIS_USER: $(IIS_USER) + # IIS_PASSWORD: $(IIS_PASSWORD) diff --git a/deploy.ps1 b/deploy.ps1 new file mode 100644 index 0000000..e16c25e --- /dev/null +++ b/deploy.ps1 @@ -0,0 +1,31 @@ +param( + [string]$RunId +) + +$storageAccount = "testvmgroupb7e2" +$container = "artifacts" +$blobName = "CircleApp_$RunId.zip" +$destFile = "C:\temp\CircleApp.zip" +$destPath = "C:\inetpub\wwwroot\CircleApp" + +Write-Output "Logging into Azure with VM's Managed Identity or SPN (assumes permissions are already granted)..." +az login --identity | Out-Null + +Write-Output "Downloading blob $blobName..." +az storage blob download ` + --account-name $storageAccount ` + --container-name $container ` + --name $blobName ` + --file $destFile ` + --auth-mode login ` + --overwrite + +Write-Output "Deploying to IIS path..." +if (Test-Path $destPath) { Remove-Item -Recurse -Force $destPath } +Expand-Archive -Path $destFile -DestinationPath $destPath -Force + +Write-Output "Restarting IIS App Pool..." +Import-Module WebAdministration +Restart-WebAppPool "DefaultAppPool" + +Write-Output "Deployment complete!" diff --git a/deploytest.ps1 b/deploytest.ps1 new file mode 100644 index 0000000..2c5d730 --- /dev/null +++ b/deploytest.ps1 @@ -0,0 +1,32 @@ +param ( + [string]$ZipPath = "C:\Temp\CircleApp.zip", + [string]$SitePath = "C:\inetpub\wwwroot\CircleApp", + [string]$AppPool = "DefaultAppPool" +) + +Write-Host "Deploying $ZipPath to $SitePath" + +# Ensure site directory exists +if (-not (Test-Path $SitePath)) { + New-Item -ItemType Directory -Path $SitePath | Out-Null +} + +# Stop App Pool +Write-Host "Stopping App Pool $AppPool..." +Stop-WebAppPool -Name $AppPool -ErrorAction SilentlyContinue + +# Extract artifact +Write-Host "Extracting $ZipPath into $SitePath..." +Expand-Archive -Path $ZipPath -DestinationPath $SitePath -Force + +# Restart App Pool +$state = (Get-WebAppPoolState -Name $AppPool).Value +if ($state -eq "Stopped") { + Write-Host "App Pool was stopped. Starting..." + Start-WebAppPool -Name $AppPool +} else { + Write-Host "Restarting App Pool..." + Restart-WebAppPool -Name $AppPool +} + +Write-Host "✅ Deployment complete!" diff --git a/scripts/deploy.ps1 b/scripts/deploy.ps1 new file mode 100644 index 0000000..e16c25e --- /dev/null +++ b/scripts/deploy.ps1 @@ -0,0 +1,31 @@ +param( + [string]$RunId +) + +$storageAccount = "testvmgroupb7e2" +$container = "artifacts" +$blobName = "CircleApp_$RunId.zip" +$destFile = "C:\temp\CircleApp.zip" +$destPath = "C:\inetpub\wwwroot\CircleApp" + +Write-Output "Logging into Azure with VM's Managed Identity or SPN (assumes permissions are already granted)..." +az login --identity | Out-Null + +Write-Output "Downloading blob $blobName..." +az storage blob download ` + --account-name $storageAccount ` + --container-name $container ` + --name $blobName ` + --file $destFile ` + --auth-mode login ` + --overwrite + +Write-Output "Deploying to IIS path..." +if (Test-Path $destPath) { Remove-Item -Recurse -Force $destPath } +Expand-Archive -Path $destFile -DestinationPath $destPath -Force + +Write-Output "Restarting IIS App Pool..." +Import-Module WebAdministration +Restart-WebAppPool "DefaultAppPool" + +Write-Output "Deployment complete!"