Build, test and upload .msi to S3 #369
This file contains 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: Build, test and upload .msi to S3 | |
# TODO: add scheduler and tests | |
on: | |
workflow_dispatch: | |
inputs: | |
ref_name: | |
required: true | |
type: string | |
workflow_call: | |
inputs: | |
ref_name: | |
required: true | |
type: string | |
schedule: | |
- cron: '0 9 * * *' | |
env: | |
GO111MODULE: on | |
GO_VERSION: '1.22.9' | |
permissions: | |
# This is required for configure-aws-credentials to request an OIDC JWT ID token to access AWS resources later on. | |
# More info: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#adding-permissions-settings | |
id-token: write | |
contents: read # This is required for actions/checkout | |
jobs: | |
get-tag-name: | |
name: Get tag name | |
runs-on: ubuntu-latest | |
outputs: | |
tag: ${{ steps.check-tag.outputs.tag }} | |
version: ${{ steps.check-tag.outputs.version }} | |
steps: | |
- name: Check tag from workflow input and github ref | |
id: check-tag | |
run: | | |
if [ -n "${{ inputs.ref_name }}" ]; then | |
tag=${{ inputs.ref_name }} | |
else | |
tag=${{ github.ref_name }} | |
fi | |
echo "tag=$tag" >> ${GITHUB_OUTPUT} | |
version=${tag#v} | |
if [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "Version matches format: $version" | |
else | |
echo "Version $version doesn't match format. Using test version: 0.0.1" | |
version="0.0.1" | |
fi | |
echo "version=$version" >> ${GITHUB_OUTPUT} | |
windows-msi-build: | |
needs: get-tag-name | |
runs-on: [self-hosted, windows, amd64, release] | |
timeout-minutes: 100 | |
steps: | |
- name: Configure git CRLF settings | |
run: | | |
git config --global core.autocrlf false | |
git config --global core.eol lf | |
- name: Set up Python | |
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 | |
with: | |
python-version: '3.x' | |
- name: Install AWS CLI | |
run: | | |
python -m pip install --upgrade pip | |
pip install awscli | |
- uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 | |
with: | |
go-version: ${{ env.GO_VERSION }} | |
cache: false | |
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
ref: ${{ needs.get-tag-name.outputs.tag }} | |
fetch-depth: 0 | |
persist-credentials: false | |
submodules: recursive | |
- name: configure aws credentials | |
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 | |
with: | |
role-to-assume: ${{ secrets.WINDOWS_ROLE }} | |
role-session-name: windows-msi | |
aws-region: ${{ secrets.WINDOWS_REGION }} | |
- name: Remove Finch VM | |
timeout-minutes: 2 | |
shell: pwsh | |
run: ./scripts/cleanup_wsl.ps1 | |
- name: Clean up previous files | |
run: | | |
takeown /F C:\actions-runner\_work\finch /R | |
Remove-Item C:\Users\Administrator\.finch -Recurse -ErrorAction Ignore | |
Remove-Item C:\Users\Administrator\AppData\Local\.finch -Recurse -ErrorAction Ignore | |
make clean | |
cd deps/finch-core && make clean | |
- name: Build project | |
run: | | |
make FINCH_OS_IMAGE_LOCATION_ROOT=__INSTALLFOLDER__ | |
- name: generate and download signed msi | |
run: | | |
$version="${{ needs.get-tag-name.outputs.version }}" | |
$tag="${{ needs.get-tag-name.outputs.tag }}" | |
powershell .\msi-builder\BuildFinchMSI.ps1 -Version $version | |
$timestamp=[math]::truncate((Get-Date (Get-Date).ToUniversalTime() -UFormat "%s")) | |
$unsignedMSI="Finch-$tag-$timestamp.msi" | |
Write-Host "Upload unsigned MSI: $unsignedMSI" | |
aws s3 cp "./msi-builder/build/Finch-$version.msi" "${{ secrets.WINDOWS_UNSIGNED_BUCKET }}$unsignedMSI" --acl bucket-owner-full-control --no-progress | |
New-Item -Path "./msi-builder/build/signed/" -ItemType Directory -Force | |
Write-Host "Attemp to download signed MSI" | |
$retryCount = 0 | |
$maxRetries = 20 | |
$delay = 5 | |
while ($retryCount -lt $maxRetries) { | |
Start-Sleep -Seconds $delay | |
$signedMSI = aws s3 ls ${{ secrets.WINDOWS_SIGNED_BUCKET }} 2>&1 | Where-Object { $_ -match "$unsignedMSI" } | Sort-Object -Descending | Select-Object -First 1 | ForEach-Object { ($_ -split '\s+')[-1] } | |
if ($signedMSI -and ($signedMSI -notlike "*An error occurred (404) when calling the HeadObject operation*")) { | |
try { | |
aws s3 cp "${{ secrets.WINDOWS_SIGNED_BUCKET }}$signedMSI" "./msi-builder/build/signed/Finch-$tag.msi" | |
break | |
} catch { | |
Write-Host "Error during copy: $_" | |
} | |
} else { | |
$retryCount++ | |
Write-Host "Unable to find the signed MSI or encountered an error. Retry $retryCount/$maxRetries..." | |
} | |
} | |
if ($retryCount -eq $maxRetries) { | |
throw "Failed after $maxRetries attempts." | |
} | |
- name: configure aws credentials for upload signed MSI to installer bucket | |
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 | |
with: | |
role-to-assume: ${{ secrets.ROLE }} | |
role-session-name: windows-msi | |
aws-region: ${{ secrets.REGION }} | |
- name: upload signed MSI to S3 | |
run: | | |
$tag="${{ needs.get-tag-name.outputs.tag }}" | |
aws s3 cp "./msi-builder/build/signed/Finch-$tag.msi" "s3://${{ secrets.INSTALLER_PRIVATE_BUCKET_NAME }}/Finch-$tag.msi" --no-progress | |
- name: Remove Finch VM and Clean Up Previous Environment | |
if: ${{ always() }} | |
timeout-minutes: 2 | |
shell: pwsh | |
run: | | |
./scripts/cleanup_wsl.ps1 | |
make clean | |
cd deps/finch-core && make clean | |
exit 0 # Cleanup may set the exit code e.g. if a file doesn't exist; just ignore | |
msi-e2e-tests: | |
needs: | |
- get-tag-name | |
- windows-msi-build | |
strategy: | |
fail-fast: false | |
runs-on: [self-hosted, windows, amd64, release] | |
timeout-minutes: 180 | |
steps: | |
- name: Configure git CRLF settings | |
run: | | |
git config --global core.autocrlf false | |
git config --global core.eol lf | |
- name: Set up Python | |
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 | |
with: | |
python-version: '3.x' | |
- name: Install AWS CLI | |
run: | | |
python -m pip install --upgrade pip | |
pip install awscli | |
- uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 | |
with: | |
go-version: ${{ env.GO_VERSION }} | |
cache: false | |
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
ref: ${{ needs.get-tag-name.outputs.tag }} | |
fetch-depth: 0 | |
persist-credentials: false | |
submodules: recursive | |
- name: Set output variables | |
id: vars | |
run: | | |
$has_creds="${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}" | |
echo "has_creds=$has_creds" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append | |
exit 0 # if $has_creds is false, powershell will exit with code 1 and this step will fail | |
- name: configure aws credentials | |
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 | |
with: | |
role-to-assume: ${{ secrets.ROLE }} | |
role-session-name: msi-test | |
aws-region: ${{ secrets.REGION }} | |
- name: Remove Finch VM | |
timeout-minutes: 2 | |
shell: pwsh | |
run: ./scripts/cleanup_wsl.ps1 | |
- name: Clean up previous files | |
run: | | |
Remove-Item C:\Users\Administrator\.finch -Recurse -ErrorAction Ignore | |
Remove-Item C:\Users\Administrator\AppData\Local\.finch -Recurse -ErrorAction Ignore | |
make clean | |
cd deps/finch-core && make clean | |
- name: Uninstall Finch silently | |
run: | | |
$productCode = (Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like "*Finch*" } | Select-Object -ExpandProperty IdentifyingNumber) | |
if ($productCode) { | |
msiexec /x $productCode /qn | |
} else { | |
Write-Output "Finch not found or it wasn't installed using MSI." | |
} | |
- name: Download MSI from S3 | |
run: | | |
$tag="${{ needs.get-tag-name.outputs.tag }}" | |
aws s3 cp "s3://${{ secrets.INSTALLER_PRIVATE_BUCKET_NAME }}/Finch-$tag.msi" ./Finch.msi | |
- name: Install MSI silently | |
run: | | |
Start-Process 'Finch.msi' -ArgumentList '/quiet' -Wait | |
echo "C:\Program Files\Finch\bin" >> $env:GITHUB_PATH | |
- name: Run VM e2e tests | |
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0 | |
with: | |
timeout_minutes: 180 | |
max_attempts: 3 | |
command: | | |
# set path to use newer ssh version | |
$newPath = (";C:\Program Files\Git\bin\;" + "C:\Program Files\Git\usr\bin\;" + "$env:Path") | |
$env:Path = $newPath | |
git status | |
git clean -f -d | |
$env:INSTALLED="true" | |
make test-e2e-vm | |
- name: Remove Finch VM | |
timeout-minutes: 2 | |
shell: pwsh | |
run: ./scripts/cleanup_wsl.ps1 | |
- name: Run container e2e tests | |
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0 | |
with: | |
timeout_minutes: 180 | |
max_attempts: 3 | |
command: | | |
# set path to use newer ssh version | |
$newPath = (";C:\Program Files\Git\bin\;" + "C:\Program Files\Git\usr\bin\;" + "$env:Path") | |
$env:Path = $newPath | |
git status | |
git clean -f -d | |
$env:INSTALLED="true" | |
make test-e2e-container | |
- name: Uninstall Finch silently | |
if: ${{ always() }} | |
run: | | |
$productCode = (Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like "*Finch*" } | Select-Object -ExpandProperty IdentifyingNumber) | |
if ($productCode) { | |
msiexec /x $productCode /qn | |
} else { | |
Write-Output "Finch not found or it wasn't installed using MSI." | |
} | |
- name: Remove Finch VM and Clean Up Previous Environment | |
if: ${{ always() }} | |
timeout-minutes: 2 | |
shell: pwsh | |
run: | | |
./scripts/cleanup_wsl.ps1 | |
make clean | |
cd deps/finch-core && make clean | |
exit 0 # Cleanup may set the exit code e.g. if a file doesn't exist; just ignore |