Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run on GitHub-hosted runners #1

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 29 additions & 65 deletions .github/workflows/git-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ defaults:

jobs:
pkg:
runs-on: ${{ github.event.inputs.architecture == 'aarch64' && fromJSON('["Windows", "ARM64"]') || 'windows-latest' }}
runs-on: ${{ github.event.inputs.architecture == 'aarch64' && 'dennis-windows-arm64' || 'windows-latest' }}
outputs:
artifact_matrix: ${{steps.artifact-build-matrix.outputs.matrix}}
msystem: ${{steps.configure-environment.outputs.MSYSTEM}}
Expand All @@ -53,6 +53,18 @@ jobs:
steps:
- name: clone git-for-windows-automation
uses: actions/checkout@v4
- name: Install build dependencies
shell: powershell
run: |
& ./azure-self-hosted-runners/post-deployment-script.ps1
Add-Content $env:GITHUB_PATH "C:\Program Files\Git\bin"
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
$newPath = 'C:\Program Files\Git\bin;' + $currentPath
[Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")
# Clone again because the original one was downloaded using a fallback method
# (since Git wasn't available yet)
- name: clone git-for-windows-automation again using Git
uses: actions/checkout@v4
- name: Construct bundle-artifacts from existing tag
if: env.EXISTING_GIT_TAG != ''
run: |
Expand Down Expand Up @@ -115,19 +127,6 @@ jobs:
unzip bundle-artifacts.zip -d bundle-artifacts
echo "GIT_VERSION=$(cat bundle-artifacts/next_version)" >> $GITHUB_ENV
echo "GIT_REV=$(cat bundle-artifacts/git-commit-oid)" >>$GITHUB_ENV
- name: Mirror Check Run to ${{ env.OWNER }}/${{ env.REPO }}
uses: ./.github/actions/check-run-action
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
owner: ${{ env.OWNER }}
repo: ${{ env.REPO }}
rev: ${{ env.GIT_REV }}
check-run-name: "git-artifacts-${{ env.ARCHITECTURE }}"
title: "Build Git ${{ env.GIT_VERSION }} artifacts"
summary: "Build Git ${{ env.GIT_VERSION }} artifacts from commit ${{ env.GIT_REV }}${{ env.TAG_GIT_WORKFLOW_RUN_ID && format(' (tag-git run #{0})', env.TAG_GIT_WORKFLOW_RUN_ID) || '' }}"
text: "For details, see [this run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id}})."
details-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id}}"
- name: Re-publish bundle-artifacts so the next job can easily use it
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -270,13 +269,6 @@ jobs:
git config --global user.email "<${info#*<}"
env:
GPGKEY: ${{secrets.GPGKEY}}
- name: update check-run
if: steps.restore-cached-git-pkg.outputs.cache-hit != 'true'
uses: ./.github/actions/check-run-action
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
append-text: 'About to build the `${{env.MINGW_PACKAGE_PREFIX}}-git` package'
- name: Build ${{env.MINGW_PACKAGE_PREFIX}}-git
timeout-minutes: 60
if: steps.restore-cached-git-pkg.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -322,12 +314,6 @@ jobs:
with:
path: artifacts
key: pkg-${{env.GIT_VERSION}}-${{env.ARCHITECTURE}}-${{env.TAG_GIT_WORKFLOW_RUN_ID}}
- name: update check-run
uses: ./.github/actions/check-run-action
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
append-text: 'The `${{env.MINGW_PACKAGE_PREFIX}}-git` package was built successfully'
- name: Publish ${{env.MINGW_PACKAGE_PREFIX}}-git
uses: actions/upload-artifact@v4
with:
Expand All @@ -337,16 +323,8 @@ jobs:
id: check-run-state
run: |
echo "check-run-state=$(base64 -w 0 <"$RUNNER_TEMP/check-run.state")" >>$GITHUB_OUTPUT
- name: update check-run if failed or canceled
if: failure() || cancelled()
uses: ./.github/actions/check-run-action
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
append-text: "${{ format('Completed: {0}', job.status) }}."
conclusion: ${{ job.status }}
artifacts:
runs-on: ${{ github.event.inputs.architecture == 'aarch64' && fromJSON('["Windows", "ARM64"]') || 'windows-latest' }}
runs-on: ${{ github.event.inputs.architecture == 'aarch64' && 'dennis-windows-arm64' || 'windows-latest' }}
needs: pkg
env:
MSYSTEM: ${{ needs.pkg.outputs.msystem }}
Expand All @@ -364,7 +342,18 @@ jobs:
sha256sum-nuget: ${{ steps.build.outputs.sha256sum-nuget }}
steps:
- name: clone git-for-windows-automation
if: needs.pkg.outputs.check-run-state != '' && always()
uses: actions/checkout@v4
- name: Install build dependencies
shell: powershell
run: |
& ./azure-self-hosted-runners/post-deployment-script.ps1
Add-Content $env:GITHUB_PATH "C:\Program Files\Git\bin"
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
$newPath = 'C:\Program Files\Git\bin;' + $currentPath
[Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")
# Clone again because the original one was downloaded using a fallback method
# (since Git wasn't available yet)
- name: clone git-for-windows-automation again using Git
uses: actions/checkout@v4
- name: Download pkg-${{env.ARCHITECTURE}}
uses: actions/download-artifact@v4
Expand Down Expand Up @@ -459,28 +448,11 @@ jobs:
with:
name: ${{matrix.artifact.name}}-${{env.ARCHITECTURE}}
path: artifacts
- name: restore check-run state
if: needs.pkg.outputs.check-run-state != '' && always()
id: check-run-state
run: |
base64 -d <(echo "${{ needs.pkg.outputs.check-run-state }}") >"$RUNNER_TEMP/check-run.state"
- name: update check-run
if: needs.pkg.outputs.check-run-state != ''
uses: ./.github/actions/check-run-action
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
append-text: 'Built ${{ matrix.artifact.name }}'
- name: update check-run if failed or canceled
if: needs.pkg.outputs.check-run-state != '' && (failure() || cancelled())
uses: ./.github/actions/check-run-action
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
append-text: "${{ format('Completed: {0}', job.status) }}."
conclusion: ${{ job.status }}
sha256sums:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
needs: ['pkg', 'artifacts']
steps:
- name: gather all SHA-256 checksums
Expand All @@ -505,11 +477,3 @@ jobs:
id: check-run-state
run: |
base64 -d <(echo "${{ needs.pkg.outputs.check-run-state }}") >"$RUNNER_TEMP/check-run.state"
- name: update check-run
if: needs.pkg.outputs.check-run-state != '' && always()
uses: ./.github/actions/check-run-action
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
append-text: "${{ job.status == 'success' && 'Done!' || format('Completed: {0}', job.status) }}."
conclusion: ${{ job.status }}
103 changes: 0 additions & 103 deletions azure-self-hosted-runners/post-deployment-script.ps1
Original file line number Diff line number Diff line change
@@ -1,27 +1,3 @@
param (
# https://docs.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners
[Parameter(Mandatory = $true, HelpMessage = "GitHub Actions Runner registration token. Note that these tokens are only valid for one hour after creation, so we always expect the user to provide one.")]
[string]$GitHubActionsRunnerToken,

# GitHub Actions Runner repository. E.g. "https://github.com/MY_ORG" (org-level) or "https://github.com/MY_ORG/MY_REPO" (repo-level)
# https://docs.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners
[Parameter(Mandatory = $true)]
[ValidateScript({ $_ -like "https://*" })]
[string]$GithubActionsRunnerRegistrationUrl,

[Parameter(Mandatory = $true, HelpMessage = "Name of the runner. Needs to be unique in the org/repo")]
[ValidateNotNullOrEmpty()]
[string]$GithubActionsRunnerName,

[Parameter(Mandatory = $false, HelpMessage = "Stop Service immediately (useful for spinning up runners preemptively)")]
[ValidateSet('true', 'false')]
[string]$StopService = 'true',

[Parameter(Mandatory = $true, HelpMessage = "Path to the Actions Runner. Keep this path short to prevent Long Path issues, e.g. D:\a")]
[ValidateNotNullOrEmpty()]
[string]$GitHubActionsRunnerPath
)

Write-Output "Starting post-deployment script."

# =================================
Expand Down Expand Up @@ -243,82 +219,3 @@ Write-Output "Copying pwsh-preview.cmd to pwsh.cmd as a temporary measure until
Copy-Item "C:\Program Files\PowerShell\7-preview\preview\pwsh-preview.cmd" "C:\Program Files\PowerShell\7-preview\preview\pwsh.cmd"

Write-Output "Finished installing pwsh."

# ======================
# GITHUB ACTIONS RUNNER
# ======================

Write-Output "Downloading GitHub Actions runner..."

mkdir $GitHubActionsRunnerPath | Out-Null
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -UseBasicParsing -Uri $GitHubAction.DownloadUrl -OutFile $GitHubAction.OutFile
$ProgressPreference = 'Continue'

if ((Get-FileHash -Path $GitHubAction.OutFile -Algorithm SHA256).Hash.ToUpper() -ne $GitHubAction.hash) {
Write-Error "Computed checksum for $($GitHubAction.OutFile) did not match $($GitHubAction.hash)"
exit 1
}

Write-Output "Installing GitHub Actions runner $($GitHubAction.Tag) as a Windows service with labels $($GitHubAction.RunnerLabels)..."

Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::ExtractToDirectory($GitHubAction.OutFile, $GitHubActionsRunnerPath)

Write-Output "Configuring the runner to shut down automatically after running"
Set-Content -Path "${GitHubActionsRunnerPath}\shut-down.ps1" -Value "shutdown -s -t 60 -d p:4:0 -c `"workflow job is done`""
[System.Environment]::SetEnvironmentVariable("ACTIONS_RUNNER_HOOK_JOB_COMPLETED", "${GitHubActionsRunnerPath}\shut-down.ps1", [System.EnvironmentVariableTarget]::Machine)

Write-Output "Configuring the runner"
cmd.exe /c "${GitHubActionsRunnerPath}\config.cmd" --unattended --ephemeral --name ${GithubActionsRunnerName} --runasservice --labels $($GitHubAction.RunnerLabels) --url ${GithubActionsRunnerRegistrationUrl} --token ${GitHubActionsRunnerToken}

# Ensure that the service was created. If not, exit with error code.
if ($null -eq (Get-Service -Name "actions.runner.*")) {
Write-Output "Could not find service actions.runner.*, making three more attempts with a 3 second delay in between each attempt..."

[int]$RetryCountService = 0
do {
Write-Output "Attempt $($RetryCountService) of 3: Looking for service actions.runner.*..."
$RetryCountService++
Start-Sleep -Seconds 3
}
while ($null -eq (Get-Service -Name "actions.runner.*") -or $RetryCountService -gt 3)

if ($RetryCountService -gt 3) {
Write-Error "GitHub Actions service not found (should start with actions.runner). Check the logs in ${GitHubActionsRunnerPath}\_diag for more details."
exit 1
}
else {
Write-Output "Found service actions.runner.*"
}
}

# Immediately stop the service as we want to leave the VM in a deallocated state for later use. The service will automatically be started when Windows starts.
if ($StopService -eq 'true') {
#Collects all running services named actions.runner.*
$GetActionRunnerServices = Get-Service -Name "actions.runner.*" | Where-Object { $_.Status -eq 'Running' } | Select-Object -ExpandProperty Name

# Loops trough all services and stopping them one by one
foreach ($Service in $GetActionRunnerServices) {
Write-Output "Stopping service $Service"
Stop-Service -Name $Service

# Making sure that all of the services has been stopped before moving forward
[int]$RetryCount = 0
do {
Write-Output "Attempt: $($RetryCount) of 5: Waiting for service $Service to stop..."
$RetryCount++
Start-Sleep -Seconds 5
}
while ((Get-Service -Name $Service).Status -eq 'running' -or $RetryCount -gt 5)

if ($RetryCount -gt 5) {
Write-Error "Service $Service failed to stop"
exit 1
}
else {
Write-Output "Service $Service has been stopped"
}
}
}

Write-Output "Finished installing GitHub Actions runner."