mirror of
https://github.com/actions/runner.git
synced 2025-12-10 20:36:49 +00:00
Compare commits
4 Commits
chore/npm-
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
659915810c | ||
|
|
ea03aa2a6e | ||
|
|
691793a922 | ||
|
|
f11013518c |
@@ -4,7 +4,7 @@
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
|
||||
"ghcr.io/devcontainers/features/dotnet": {
|
||||
"version": "8.0.413"
|
||||
"version": "8.0.412"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "20"
|
||||
|
||||
2
.github/workflows/close-bugs-bot.yml
vendored
2
.github/workflows/close-bugs-bot.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
close-issue-message: "This issue does not seem to be a problem with the runner application, it concerns the GitHub actions platform more generally. Could you please post your feedback on the [GitHub Community Support Forum](https://github.com/orgs/community/discussions/categories/actions) which is actively monitored. Using the forum ensures that we route your problem to the correct team. 😃"
|
||||
exempt-issue-labels: "keep"
|
||||
|
||||
2
.github/workflows/close-features-bot.yml
vendored
2
.github/workflows/close-features-bot.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
close-issue-message: "Thank you for your interest in the runner application and taking the time to provide your valuable feedback. We kindly ask you to redirect this feedback to the [GitHub Community Support Forum](https://github.com/orgs/community/discussions/categories/actions-and-packages) which our team actively monitors and would be a better place to start a discussion for new feature requests in GitHub Actions. For more information on this policy please [read our contribution guidelines](https://github.com/actions/runner#contribute). 😃"
|
||||
exempt-issue-labels: "keep"
|
||||
|
||||
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
uses: github/codeql-action/init@v3
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
@@ -38,4 +38,4 @@ jobs:
|
||||
working-directory: src
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
211
.github/workflows/dependency-check.yml
vendored
211
.github/workflows/dependency-check.yml
vendored
@@ -1,211 +0,0 @@
|
||||
name: Dependency Status Check
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
check_type:
|
||||
description: "Type of dependency check"
|
||||
required: false
|
||||
default: "all"
|
||||
type: choice
|
||||
options:
|
||||
- all
|
||||
- node
|
||||
- dotnet
|
||||
- docker
|
||||
- npm
|
||||
schedule:
|
||||
- cron: "0 11 * * 1" # Weekly on Monday at 11 AM
|
||||
|
||||
jobs:
|
||||
dependency-status:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
node20-status: ${{ steps.check-versions.outputs.node20-status }}
|
||||
node24-status: ${{ steps.check-versions.outputs.node24-status }}
|
||||
dotnet-status: ${{ steps.check-versions.outputs.dotnet-status }}
|
||||
docker-status: ${{ steps.check-versions.outputs.docker-status }}
|
||||
buildx-status: ${{ steps.check-versions.outputs.buildx-status }}
|
||||
npm-vulnerabilities: ${{ steps.check-versions.outputs.npm-vulnerabilities }}
|
||||
open-dependency-prs: ${{ steps.check-prs.outputs.open-dependency-prs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- name: Check dependency versions
|
||||
id: check-versions
|
||||
run: |
|
||||
echo "## Dependency Status Report" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Generated on: $(date)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Check Node versions
|
||||
if [[ "${{ github.event.inputs.check_type }}" == "all" || "${{ github.event.inputs.check_type }}" == "node" ]]; then
|
||||
echo "### Node.js Versions" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
VERSIONS_JSON=$(curl -s https://raw.githubusercontent.com/actions/node-versions/main/versions-manifest.json)
|
||||
LATEST_NODE20=$(echo "$VERSIONS_JSON" | jq -r '.[] | select(.version | startswith("20.")) | .version' | head -1)
|
||||
LATEST_NODE24=$(echo "$VERSIONS_JSON" | jq -r '.[] | select(.version | startswith("24.")) | .version' | head -1)
|
||||
|
||||
CURRENT_NODE20=$(grep "NODE20_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
|
||||
CURRENT_NODE24=$(grep "NODE24_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
|
||||
|
||||
NODE20_STATUS="✅ up-to-date"
|
||||
NODE24_STATUS="✅ up-to-date"
|
||||
|
||||
if [ "$CURRENT_NODE20" != "$LATEST_NODE20" ]; then
|
||||
NODE20_STATUS="⚠️ outdated"
|
||||
fi
|
||||
|
||||
if [ "$CURRENT_NODE24" != "$LATEST_NODE24" ]; then
|
||||
NODE24_STATUS="⚠️ outdated"
|
||||
fi
|
||||
|
||||
echo "| Version | Current | Latest | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|---------|---------|--------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Node 20 | $CURRENT_NODE20 | $LATEST_NODE20 | $NODE20_STATUS |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Node 24 | $CURRENT_NODE24 | $LATEST_NODE24 | $NODE24_STATUS |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
echo "node20-status=$NODE20_STATUS" >> $GITHUB_OUTPUT
|
||||
echo "node24-status=$NODE24_STATUS" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Check .NET version
|
||||
if [[ "${{ github.event.inputs.check_type }}" == "all" || "${{ github.event.inputs.check_type }}" == "dotnet" ]]; then
|
||||
echo "### .NET SDK Version" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
current_dotnet_version=$(jq -r .sdk.version ./src/global.json)
|
||||
current_major_minor=$(echo "$current_dotnet_version" | cut -d '.' -f 1,2)
|
||||
latest_dotnet_version=$(curl -sb -H "Accept: application/json" "https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$current_major_minor/latest.version")
|
||||
|
||||
DOTNET_STATUS="✅ up-to-date"
|
||||
if [ "$current_dotnet_version" != "$latest_dotnet_version" ]; then
|
||||
DOTNET_STATUS="⚠️ outdated"
|
||||
fi
|
||||
|
||||
echo "| Component | Current | Latest | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-----------|---------|--------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| .NET SDK | $current_dotnet_version | $latest_dotnet_version | $DOTNET_STATUS |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
echo "dotnet-status=$DOTNET_STATUS" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Check Docker versions
|
||||
if [[ "${{ github.event.inputs.check_type }}" == "all" || "${{ github.event.inputs.check_type }}" == "docker" ]]; then
|
||||
echo "### Docker Versions" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
current_docker=$(grep "ARG DOCKER_VERSION=" ./images/Dockerfile | cut -d'=' -f2)
|
||||
current_buildx=$(grep "ARG BUILDX_VERSION=" ./images/Dockerfile | cut -d'=' -f2)
|
||||
|
||||
latest_docker=$(curl -s https://download.docker.com/linux/static/stable/x86_64/ | grep -o 'docker-[0-9]*\.[0-9]*\.[0-9]*\.tgz' | sort -V | tail -n 1 | sed 's/docker-\(.*\)\.tgz/\1/')
|
||||
latest_buildx=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | jq -r '.tag_name' | sed 's/^v//')
|
||||
|
||||
DOCKER_STATUS="✅ up-to-date"
|
||||
BUILDX_STATUS="✅ up-to-date"
|
||||
|
||||
if [ "$current_docker" != "$latest_docker" ]; then
|
||||
DOCKER_STATUS="⚠️ outdated"
|
||||
fi
|
||||
|
||||
if [ "$current_buildx" != "$latest_buildx" ]; then
|
||||
BUILDX_STATUS="⚠️ outdated"
|
||||
fi
|
||||
|
||||
echo "| Component | Current | Latest | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-----------|---------|--------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Docker | $current_docker | $latest_docker | $DOCKER_STATUS |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Docker Buildx | $current_buildx | $latest_buildx | $BUILDX_STATUS |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
echo "docker-status=$DOCKER_STATUS" >> $GITHUB_OUTPUT
|
||||
echo "buildx-status=$BUILDX_STATUS" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Check npm vulnerabilities
|
||||
if [[ "${{ github.event.inputs.check_type }}" == "all" || "${{ github.event.inputs.check_type }}" == "npm" ]]; then
|
||||
echo "### NPM Security Audit" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
cd src/Misc/expressionFunc/hashFiles
|
||||
npm install --silent
|
||||
|
||||
AUDIT_OUTPUT=""
|
||||
AUDIT_EXIT_CODE=0
|
||||
# Run npm audit and capture output and exit code
|
||||
if ! AUDIT_OUTPUT=$(npm audit --json 2>&1); then
|
||||
AUDIT_EXIT_CODE=$?
|
||||
fi
|
||||
|
||||
# Check if output is valid JSON
|
||||
if echo "$AUDIT_OUTPUT" | jq . >/dev/null 2>&1; then
|
||||
VULN_COUNT=$(echo "$AUDIT_OUTPUT" | jq '.metadata.vulnerabilities.total // 0')
|
||||
# Ensure VULN_COUNT is a number
|
||||
VULN_COUNT=$(echo "$VULN_COUNT" | grep -o '[0-9]*' | head -1)
|
||||
VULN_COUNT=${VULN_COUNT:-0}
|
||||
|
||||
NPM_STATUS="✅ no vulnerabilities"
|
||||
if [ "$VULN_COUNT" -gt 0 ] 2>/dev/null; then
|
||||
NPM_STATUS="⚠️ $VULN_COUNT vulnerabilities found"
|
||||
|
||||
# Get vulnerability details
|
||||
HIGH_VULNS=$(echo "$AUDIT_OUTPUT" | jq '.metadata.vulnerabilities.high // 0')
|
||||
CRITICAL_VULNS=$(echo "$AUDIT_OUTPUT" | jq '.metadata.vulnerabilities.critical // 0')
|
||||
|
||||
echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Critical | $CRITICAL_VULNS |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| High | $HIGH_VULNS |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "No npm vulnerabilities found ✅" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
else
|
||||
NPM_STATUS="❌ npm audit failed"
|
||||
echo "npm audit failed to run or returned invalid JSON ❌" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Exit code: $AUDIT_EXIT_CODE" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Output: $AUDIT_OUTPUT" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
echo "npm-vulnerabilities=$NPM_STATUS" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Check for open dependency PRs
|
||||
id: check-prs
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo "### Open Dependency PRs" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Get open PRs with dependency label
|
||||
OPEN_PRS=$(gh pr list --label "dependencies" --state open --json number,title,url)
|
||||
PR_COUNT=$(echo "$OPEN_PRS" | jq '. | length')
|
||||
|
||||
if [ "$PR_COUNT" -gt 0 ]; then
|
||||
echo "Found $PR_COUNT open dependency PR(s):" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "$OPEN_PRS" | jq -r '.[] | "- [#\(.number)](\(.url)) \(.title)"' >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "No open dependency PRs found ✅" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "open-dependency-prs=$PR_COUNT" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Summary
|
||||
run: |
|
||||
echo "### Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Check for open PRs with the \`dependency\` label before releases" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Review and merge dependency updates regularly" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Critical vulnerabilities should be addressed immediately" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Automated workflows run weekly to check for updates:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Node.js versions (Mondays at 6 AM)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- NPM audit fix (Mondays at 7 AM)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- .NET SDK updates (Mondays at midnight)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Docker/Buildx updates (Mondays at midnight)" >> $GITHUB_STEP_SUMMARY
|
||||
58
.github/workflows/docker-buildx-upgrade.yml
vendored
58
.github/workflows/docker-buildx-upgrade.yml
vendored
@@ -2,8 +2,8 @@ name: "Docker/Buildx Version Upgrade"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * 1" # Run every Monday at midnight
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
- cron: '0 0 * * 1' # Run every Monday at midnight
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
|
||||
jobs:
|
||||
check-versions:
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
echo "Failed to retrieve a valid Docker version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
should_update=0
|
||||
[ "$current_version" != "$latest_version" ] && should_update=1
|
||||
|
||||
@@ -64,17 +64,17 @@ jobs:
|
||||
run: |
|
||||
docker_should_update="${{ steps.check_docker_version.outputs.SHOULD_UPDATE }}"
|
||||
buildx_should_update="${{ steps.check_buildx_version.outputs.SHOULD_UPDATE }}"
|
||||
|
||||
|
||||
# Show annotation if only Docker needs update
|
||||
if [[ "$docker_should_update" == "1" && "$buildx_should_update" == "0" ]]; then
|
||||
echo "::warning ::Docker version (${{ steps.check_docker_version.outputs.LATEST_VERSION }}) needs update but Buildx is current. Only updating when both need updates."
|
||||
fi
|
||||
|
||||
|
||||
# Show annotation if only Buildx needs update
|
||||
if [[ "$docker_should_update" == "0" && "$buildx_should_update" == "1" ]]; then
|
||||
echo "::warning ::Buildx version (${{ steps.check_buildx_version.outputs.LATEST_VERSION }}) needs update but Docker is current. Only updating when both need updates."
|
||||
fi
|
||||
|
||||
|
||||
# Show annotation when both are current
|
||||
if [[ "$docker_should_update" == "0" && "$buildx_should_update" == "0" ]]; then
|
||||
echo "::warning ::Latest Docker version is ${{ steps.check_docker_version.outputs.LATEST_VERSION }} and Buildx version is ${{ steps.check_buildx_version.outputs.LATEST_VERSION }}. No updates needed."
|
||||
@@ -90,25 +90,25 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
|
||||
- name: Update Docker version
|
||||
shell: bash
|
||||
run: |
|
||||
latest_version="${{ needs.check-versions.outputs.DOCKER_LATEST_VERSION }}"
|
||||
current_version="${{ needs.check-versions.outputs.DOCKER_CURRENT_VERSION }}"
|
||||
|
||||
|
||||
# Update version in Dockerfile
|
||||
sed -i "s/ARG DOCKER_VERSION=$current_version/ARG DOCKER_VERSION=$latest_version/g" ./images/Dockerfile
|
||||
|
||||
|
||||
- name: Update Buildx version
|
||||
shell: bash
|
||||
run: |
|
||||
latest_version="${{ needs.check-versions.outputs.BUILDX_LATEST_VERSION }}"
|
||||
current_version="${{ needs.check-versions.outputs.BUILDX_CURRENT_VERSION }}"
|
||||
|
||||
|
||||
# Update version in Dockerfile
|
||||
sed -i "s/ARG BUILDX_VERSION=$current_version/ARG BUILDX_VERSION=$latest_version/g" ./images/Dockerfile
|
||||
|
||||
|
||||
- name: Commit changes and create Pull Request
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
branch_name="feature/docker-buildx-upgrade"
|
||||
commit_message="Upgrade Docker to v${{ needs.check-versions.outputs.DOCKER_LATEST_VERSION }} and Buildx to v${{ needs.check-versions.outputs.BUILDX_LATEST_VERSION }}"
|
||||
pr_title="Update Docker to v${{ needs.check-versions.outputs.DOCKER_LATEST_VERSION }} and Buildx to v${{ needs.check-versions.outputs.BUILDX_LATEST_VERSION }}"
|
||||
|
||||
|
||||
# Configure git
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "<41898282+github-actions[bot]@users.noreply.github.com>"
|
||||
@@ -129,38 +129,16 @@ jobs:
|
||||
else
|
||||
git checkout -b "$branch_name"
|
||||
fi
|
||||
|
||||
|
||||
# Commit and push changes
|
||||
git commit -a -m "$commit_message"
|
||||
git push --force origin "$branch_name"
|
||||
|
||||
# Create PR body using here-doc for proper formatting
|
||||
cat > pr_body.txt << 'EOF'
|
||||
Automated Docker and Buildx version update:
|
||||
|
||||
- Docker: ${{ needs.check-versions.outputs.DOCKER_CURRENT_VERSION }} → ${{ needs.check-versions.outputs.DOCKER_LATEST_VERSION }}
|
||||
- Buildx: ${{ needs.check-versions.outputs.BUILDX_CURRENT_VERSION }} → ${{ needs.check-versions.outputs.BUILDX_LATEST_VERSION }}
|
||||
|
||||
This update ensures we're using the latest stable Docker and Buildx versions for security and performance improvements.
|
||||
|
||||
**Release notes:** https://docs.docker.com/engine/release-notes/
|
||||
|
||||
**Next steps:**
|
||||
- Review the version changes
|
||||
- Verify container builds work as expected
|
||||
- Test multi-platform builds if applicable
|
||||
- Merge when ready
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [Docker/Buildx Version Upgrade Workflow](https://github.com/actions/runner/blob/main/.github/workflows/docker-buildx-upgrade.yml)
|
||||
EOF
|
||||
|
||||
# Create PR
|
||||
pr_body="Upgrades Docker version from ${{ needs.check-versions.outputs.DOCKER_CURRENT_VERSION }} to ${{ needs.check-versions.outputs.DOCKER_LATEST_VERSION }} and Docker Buildx version from ${{ needs.check-versions.outputs.BUILDX_CURRENT_VERSION }} to ${{ needs.check-versions.outputs.BUILDX_LATEST_VERSION }}.\n\n"
|
||||
pr_body+="Release notes: https://docs.docker.com/engine/release-notes/\n\n"
|
||||
pr_body+="---\n\nAutogenerated by [Docker/Buildx Version Upgrade Workflow](https://github.com/actions/runner/blob/main/.github/workflows/docker-buildx-upgrade.yml)"
|
||||
|
||||
gh pr create -B main -H "$branch_name" \
|
||||
--title "$pr_title" \
|
||||
--label "dependencies" \
|
||||
--label "dependencies-weekly-check" \
|
||||
--label "dependencies-not-dependabot" \
|
||||
--label "docker" \
|
||||
--body-file pr_body.txt
|
||||
--body "$pr_body"
|
||||
|
||||
32
.github/workflows/dotnet-upgrade.yml
vendored
32
.github/workflows/dotnet-upgrade.yml
vendored
@@ -2,13 +2,13 @@ name: "DotNet SDK Upgrade"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 8 * * 1" # Weekly on Monday at 8 AM UTC (independent of Node.js/NPM)
|
||||
- cron: '0 0 * * 1'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
dotnet-update:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
outputs:
|
||||
SHOULD_UPDATE: ${{ steps.fetch_latest_version.outputs.SHOULD_UPDATE }}
|
||||
BRANCH_EXISTS: ${{ steps.fetch_latest_version.outputs.BRANCH_EXISTS }}
|
||||
DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION: ${{ steps.fetch_latest_version.outputs.DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION }}
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
|
||||
# check if git branch already exists for the upgrade
|
||||
branch_already_exists=0
|
||||
|
||||
|
||||
if git ls-remote --heads --exit-code origin refs/heads/feature/dotnetsdk-upgrade/${latest_patch_version};
|
||||
then
|
||||
branch_already_exists=1
|
||||
@@ -89,17 +89,17 @@ jobs:
|
||||
if: ${{ needs.dotnet-update.outputs.SHOULD_UPDATE == 1 && needs.dotnet-update.outputs.BRANCH_EXISTS == 0 }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: feature/dotnetsdk-upgrade/${{ needs.dotnet-update.outputs.DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION }}
|
||||
- name: Create Pull Request
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh pr create -B main -H feature/dotnetsdk-upgrade/${{ needs.dotnet-update.outputs.DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION }} --title "Update dotnet sdk to latest version @${{ needs.dotnet-update.outputs.DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION }}" --label "dependencies" --label "dependencies-weekly-check" --label "dependencies-not-dependabot" --label "dotnet" --body "
|
||||
https://dotnetcli.blob.core.windows.net/dotnet/Sdk/${{ needs.dotnet-update.outputs.DOTNET_CURRENT_MAJOR_MINOR_VERSION }}/latest.version
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: feature/dotnetsdk-upgrade/${{ needs.dotnet-update.outputs.DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION }}
|
||||
- name: Create Pull Request
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh pr create -B main -H feature/dotnetsdk-upgrade/${{ needs.dotnet-update.outputs.DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION }} --title "Update dotnet sdk to latest version @${{ needs.dotnet-update.outputs.DOTNET_LATEST_MAJOR_MINOR_PATCH_VERSION }}" --body "
|
||||
https://dotnetcli.blob.core.windows.net/dotnet/Sdk/${{ needs.dotnet-update.outputs.DOTNET_CURRENT_MAJOR_MINOR_VERSION }}/latest.version
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [DotNet SDK Upgrade Workflow](https://github.com/actions/runner/blob/main/.github/workflows/dotnet-upgrade.yml)"
|
||||
---
|
||||
|
||||
Autogenerated by [DotNet SDK Upgrade Workflow](https://github.com/actions/runner/blob/main/.github/workflows/dotnet-upgrade.yml)"
|
||||
|
||||
194
.github/workflows/node-upgrade.yml
vendored
194
.github/workflows/node-upgrade.yml
vendored
@@ -1,194 +0,0 @@
|
||||
name: Auto Update Node Version
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 6 * * 1" # Weekly, every Monday
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update-node:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Get latest Node versions
|
||||
id: node-versions
|
||||
run: |
|
||||
# Get latest Node.js releases from official GitHub releases
|
||||
echo "Fetching latest Node.js releases..."
|
||||
|
||||
# Get latest v20.x release
|
||||
LATEST_NODE20=$(curl -s https://api.github.com/repos/nodejs/node/releases | \
|
||||
jq -r '.[] | select(.tag_name | startswith("v20.")) | .tag_name' | \
|
||||
head -1 | sed 's/^v//')
|
||||
|
||||
# Get latest v24.x release
|
||||
LATEST_NODE24=$(curl -s https://api.github.com/repos/nodejs/node/releases | \
|
||||
jq -r '.[] | select(.tag_name | startswith("v24.")) | .tag_name' | \
|
||||
head -1 | sed 's/^v//')
|
||||
|
||||
echo "Found Node.js releases: 20=$LATEST_NODE20, 24=$LATEST_NODE24"
|
||||
|
||||
# Verify these versions are available in alpine_nodejs releases
|
||||
echo "Verifying availability in alpine_nodejs..."
|
||||
ALPINE_RELEASES=$(curl -s https://api.github.com/repos/actions/alpine_nodejs/releases | jq -r '.[].tag_name')
|
||||
|
||||
if ! echo "$ALPINE_RELEASES" | grep -q "^v$LATEST_NODE20$"; then
|
||||
echo "::warning title=Node 20 Fallback::Node 20 version $LATEST_NODE20 not found in alpine_nodejs releases, using fallback"
|
||||
# Fall back to latest available alpine_nodejs v20 release
|
||||
LATEST_NODE20=$(echo "$ALPINE_RELEASES" | grep "^v20\." | head -1 | sed 's/^v//')
|
||||
echo "Using latest available alpine_nodejs Node 20: $LATEST_NODE20"
|
||||
fi
|
||||
|
||||
if ! echo "$ALPINE_RELEASES" | grep -q "^v$LATEST_NODE24$"; then
|
||||
echo "::warning title=Node 24 Fallback::Node 24 version $LATEST_NODE24 not found in alpine_nodejs releases, using fallback"
|
||||
# Fall back to latest available alpine_nodejs v24 release
|
||||
LATEST_NODE24=$(echo "$ALPINE_RELEASES" | grep "^v24\." | head -1 | sed 's/^v//')
|
||||
echo "Using latest available alpine_nodejs Node 24: $LATEST_NODE24"
|
||||
fi
|
||||
|
||||
# Validate that we have non-empty version numbers
|
||||
if [ -z "$LATEST_NODE20" ] || [ "$LATEST_NODE20" = "" ]; then
|
||||
echo "::error title=Invalid Node 20 Version::Failed to determine valid Node 20 version. Got: '$LATEST_NODE20'"
|
||||
echo "Available alpine_nodejs releases:"
|
||||
echo "$ALPINE_RELEASES" | head -10
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$LATEST_NODE24" ] || [ "$LATEST_NODE24" = "" ]; then
|
||||
echo "::error title=Invalid Node 24 Version::Failed to determine valid Node 24 version. Got: '$LATEST_NODE24'"
|
||||
echo "Available alpine_nodejs releases:"
|
||||
echo "$ALPINE_RELEASES" | head -10
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Additional validation: ensure versions match expected format (x.y.z)
|
||||
if ! echo "$LATEST_NODE20" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "::error title=Invalid Node 20 Format::Node 20 version '$LATEST_NODE20' does not match expected format (x.y.z)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! echo "$LATEST_NODE24" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "::error title=Invalid Node 24 Format::Node 24 version '$LATEST_NODE24' does not match expected format (x.y.z)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Validated Node versions: 20=$LATEST_NODE20, 24=$LATEST_NODE24"
|
||||
echo "latest_node20=$LATEST_NODE20" >> $GITHUB_OUTPUT
|
||||
echo "latest_node24=$LATEST_NODE24" >> $GITHUB_OUTPUT
|
||||
|
||||
# Check current versions in externals.sh
|
||||
CURRENT_NODE20=$(grep "NODE20_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
|
||||
CURRENT_NODE24=$(grep "NODE24_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
|
||||
|
||||
echo "current_node20=$CURRENT_NODE20" >> $GITHUB_OUTPUT
|
||||
echo "current_node24=$CURRENT_NODE24" >> $GITHUB_OUTPUT
|
||||
|
||||
# Determine if updates are needed
|
||||
NEEDS_UPDATE20="false"
|
||||
NEEDS_UPDATE24="false"
|
||||
|
||||
if [ "$CURRENT_NODE20" != "$LATEST_NODE20" ]; then
|
||||
NEEDS_UPDATE20="true"
|
||||
echo "::notice title=Node 20 Update Available::Current: $CURRENT_NODE20 → Latest: $LATEST_NODE20"
|
||||
fi
|
||||
|
||||
if [ "$CURRENT_NODE24" != "$LATEST_NODE24" ]; then
|
||||
NEEDS_UPDATE24="true"
|
||||
echo "::notice title=Node 24 Update Available::Current: $CURRENT_NODE24 → Latest: $LATEST_NODE24"
|
||||
fi
|
||||
|
||||
if [ "$NEEDS_UPDATE20" == "false" ] && [ "$NEEDS_UPDATE24" == "false" ]; then
|
||||
echo "::notice title=No Updates Needed::All Node.js versions are up to date"
|
||||
fi
|
||||
|
||||
echo "needs_update20=$NEEDS_UPDATE20" >> $GITHUB_OUTPUT
|
||||
echo "needs_update24=$NEEDS_UPDATE24" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update externals.sh and create PR
|
||||
if: steps.node-versions.outputs.needs_update20 == 'true' || steps.node-versions.outputs.needs_update24 == 'true'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# Final validation before making changes
|
||||
NODE20_VERSION="${{ steps.node-versions.outputs.latest_node20 }}"
|
||||
NODE24_VERSION="${{ steps.node-versions.outputs.latest_node24 }}"
|
||||
|
||||
echo "Final validation of versions before PR creation:"
|
||||
echo "Node 20: '$NODE20_VERSION'"
|
||||
echo "Node 24: '$NODE24_VERSION'"
|
||||
|
||||
# Validate versions are not empty and match expected format
|
||||
if [ -z "$NODE20_VERSION" ] || ! echo "$NODE20_VERSION" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "::error title=Invalid Node 20 Version::Refusing to create PR with invalid Node 20 version: '$NODE20_VERSION'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$NODE24_VERSION" ] || ! echo "$NODE24_VERSION" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "::error title=Invalid Node 24 Version::Refusing to create PR with invalid Node 24 version: '$NODE24_VERSION'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ All versions validated successfully"
|
||||
|
||||
# Update the files
|
||||
if [ "${{ steps.node-versions.outputs.needs_update20 }}" == "true" ]; then
|
||||
sed -i 's/NODE20_VERSION="[^"]*"/NODE20_VERSION="'"$NODE20_VERSION"'"/' src/Misc/externals.sh
|
||||
fi
|
||||
|
||||
if [ "${{ steps.node-versions.outputs.needs_update24 }}" == "true" ]; then
|
||||
sed -i 's/NODE24_VERSION="[^"]*"/NODE24_VERSION="'"$NODE24_VERSION"'"/' src/Misc/externals.sh
|
||||
fi
|
||||
|
||||
# Verify the changes were applied correctly
|
||||
echo "Verifying changes in externals.sh:"
|
||||
grep "NODE20_VERSION=" src/Misc/externals.sh
|
||||
grep "NODE24_VERSION=" src/Misc/externals.sh
|
||||
|
||||
# Ensure we actually have valid versions in the file
|
||||
UPDATED_NODE20=$(grep "NODE20_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
|
||||
UPDATED_NODE24=$(grep "NODE24_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
|
||||
|
||||
if [ -z "$UPDATED_NODE20" ] || [ -z "$UPDATED_NODE24" ]; then
|
||||
echo "::error title=Update Failed::Failed to properly update externals.sh"
|
||||
echo "Updated Node 20: '$UPDATED_NODE20'"
|
||||
echo "Updated Node 24: '$UPDATED_NODE24'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configure git
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "<41898282+github-actions[bot]@users.noreply.github.com>"
|
||||
|
||||
# Create branch and commit changes
|
||||
branch_name="chore/update-node"
|
||||
git checkout -b "$branch_name"
|
||||
git commit -a -m "chore: update Node versions (20: $NODE20_VERSION, 24: $NODE24_VERSION)"
|
||||
git push --force origin "$branch_name"
|
||||
|
||||
# Create PR body using here-doc for proper formatting
|
||||
cat > pr_body.txt << EOF
|
||||
Automated Node.js version update:
|
||||
|
||||
- Node 20: ${{ steps.node-versions.outputs.current_node20 }} → $NODE20_VERSION
|
||||
- Node 24: ${{ steps.node-versions.outputs.current_node24 }} → $NODE24_VERSION
|
||||
|
||||
This update ensures we're using the latest stable Node.js versions for security and performance improvements.
|
||||
|
||||
**Note**: When updating Node versions, remember to also create a new release of alpine_nodejs at the updated version following the instructions at: https://github.com/actions/alpine_nodejs
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [Node Version Upgrade Workflow](https://github.com/actions/runner/blob/main/.github/workflows/node-upgrade.yml)
|
||||
EOF
|
||||
|
||||
# Create PR
|
||||
gh pr create -B main -H "$branch_name" \
|
||||
--title "chore: update Node versions" \
|
||||
--label "dependencies" \
|
||||
--label "dependencies-weekly-check" \
|
||||
--label "dependencies-not-dependabot" \
|
||||
--label "node" \
|
||||
--label "javascript" \
|
||||
--body-file pr_body.txt
|
||||
|
||||
echo "::notice title=PR Created::Successfully created Node.js version update PR on branch $branch_name"
|
||||
235
.github/workflows/npm-audit-typescript.yml
vendored
235
.github/workflows/npm-audit-typescript.yml
vendored
@@ -1,235 +0,0 @@
|
||||
name: NPM Audit Fix with TypeScript Auto-Fix
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
npm-audit-with-ts-fix:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
- name: NPM install and audit fix with TypeScript auto-repair
|
||||
working-directory: src/Misc/expressionFunc/hashFiles
|
||||
run: |
|
||||
npm install
|
||||
|
||||
# Check for vulnerabilities first
|
||||
echo "Checking for npm vulnerabilities..."
|
||||
if npm audit --audit-level=moderate; then
|
||||
echo "✅ No moderate or higher vulnerabilities found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "⚠️ Vulnerabilities found, attempting npm audit fix..."
|
||||
|
||||
# Attempt audit fix and capture the result
|
||||
if npm audit fix; then
|
||||
echo "✅ npm audit fix completed successfully"
|
||||
AUDIT_FIX_STATUS="success"
|
||||
else
|
||||
echo "⚠️ npm audit fix failed or had issues"
|
||||
AUDIT_FIX_STATUS="failed"
|
||||
|
||||
# Try audit fix with --force as a last resort for critical/high vulns only
|
||||
echo "Checking if critical/high vulnerabilities remain..."
|
||||
if ! npm audit --audit-level=high; then
|
||||
echo "🚨 Critical/high vulnerabilities remain, attempting --force fix..."
|
||||
if npm audit fix --force; then
|
||||
echo "⚠️ npm audit fix --force completed (may have breaking changes)"
|
||||
AUDIT_FIX_STATUS="force-fixed"
|
||||
else
|
||||
echo "❌ npm audit fix --force also failed"
|
||||
AUDIT_FIX_STATUS="force-failed"
|
||||
fi
|
||||
else
|
||||
echo "✅ Only moderate/low vulnerabilities remain after failed fix"
|
||||
AUDIT_FIX_STATUS="partial-success"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "AUDIT_FIX_STATUS=$AUDIT_FIX_STATUS" >> $GITHUB_ENV
|
||||
|
||||
# Try to fix TypeScript issues automatically
|
||||
echo "Attempting to fix TypeScript compatibility issues..."
|
||||
|
||||
# Check if build fails
|
||||
if ! npm run build 2>/dev/null; then
|
||||
echo "Build failed, attempting automated fixes..."
|
||||
|
||||
# Common fix 1: Update @types/node to latest compatible version
|
||||
echo "Trying to update @types/node to latest version..."
|
||||
npm update @types/node
|
||||
|
||||
# Common fix 2: If that doesn't work, try installing a specific known-good version
|
||||
if ! npm run build 2>/dev/null; then
|
||||
echo "Trying specific @types/node version..."
|
||||
# Try Node 20 compatible version
|
||||
npm install --save-dev @types/node@^20.0.0
|
||||
fi
|
||||
|
||||
# Common fix 3: Clear node_modules and reinstall if still failing
|
||||
if ! npm run build 2>/dev/null; then
|
||||
echo "Clearing node_modules and reinstalling..."
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
|
||||
# Re-run audit fix after clean install if it was successful before
|
||||
if [[ "$AUDIT_FIX_STATUS" == "success" || "$AUDIT_FIX_STATUS" == "force-fixed" ]]; then
|
||||
echo "Re-running npm audit fix after clean install..."
|
||||
npm audit fix || echo "Audit fix failed on second attempt"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Common fix 4: Try updating TypeScript itself
|
||||
if ! npm run build 2>/dev/null; then
|
||||
echo "Trying to update TypeScript..."
|
||||
npm update typescript
|
||||
fi
|
||||
|
||||
# Final check
|
||||
if npm run build 2>/dev/null; then
|
||||
echo "✅ Successfully fixed TypeScript issues automatically"
|
||||
else
|
||||
echo "⚠️ Could not automatically fix TypeScript issues"
|
||||
fi
|
||||
else
|
||||
echo "✅ Build passes after audit fix"
|
||||
fi
|
||||
|
||||
- name: Create PR if changes exist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
HUSKY: 0 # Disable husky hooks for automated commits
|
||||
run: |
|
||||
# Check if there are any changes
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
# Configure git
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "<41898282+github-actions[bot]@users.noreply.github.com>"
|
||||
|
||||
# Create branch and commit changes
|
||||
branch_name="chore/npm-audit-fix-with-ts-repair"
|
||||
git checkout -b "$branch_name"
|
||||
|
||||
# Commit with --no-verify to skip husky hooks
|
||||
git commit -a -m "chore: npm audit fix with automated TypeScript compatibility fixes" --no-verify
|
||||
git push --force origin "$branch_name"
|
||||
|
||||
# Check final build status and gather info about what was changed
|
||||
build_status="✅ Build passes"
|
||||
fixes_applied=""
|
||||
cd src/Misc/expressionFunc/hashFiles
|
||||
|
||||
# Check what packages were updated
|
||||
if git diff HEAD~1 package.json | grep -q "@types/node"; then
|
||||
fixes_applied+="\n- Updated @types/node version for TypeScript compatibility"
|
||||
fi
|
||||
if git diff HEAD~1 package.json | grep -q "typescript"; then
|
||||
fixes_applied+="\n- Updated TypeScript version"
|
||||
fi
|
||||
if git diff HEAD~1 package-lock.json | grep -q "resolved"; then
|
||||
fixes_applied+="\n- Updated package dependencies via npm audit fix"
|
||||
fi
|
||||
|
||||
if ! npm run build 2>/dev/null; then
|
||||
build_status="⚠️ Build fails - manual review required"
|
||||
fi
|
||||
cd - > /dev/null
|
||||
|
||||
# Create enhanced PR body using here-doc for proper formatting
|
||||
audit_status_msg=""
|
||||
case "$AUDIT_FIX_STATUS" in
|
||||
"success")
|
||||
audit_status_msg="✅ **Audit Fix**: Completed successfully"
|
||||
;;
|
||||
"partial-success")
|
||||
audit_status_msg="⚠️ **Audit Fix**: Partial success (only moderate/low vulnerabilities remain)"
|
||||
;;
|
||||
"force-fixed")
|
||||
audit_status_msg="⚠️ **Audit Fix**: Completed with --force (may have breaking changes)"
|
||||
;;
|
||||
"failed"|"force-failed")
|
||||
audit_status_msg="❌ **Audit Fix**: Failed to resolve vulnerabilities"
|
||||
;;
|
||||
*)
|
||||
audit_status_msg="❓ **Audit Fix**: Status unknown"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$build_status" == *"fails"* ]]; then
|
||||
cat > pr_body.txt << EOF
|
||||
Automated npm audit fix with TypeScript auto-repair for hashFiles dependencies.
|
||||
|
||||
**Build Status**: ⚠️ Build fails - manual review required
|
||||
$audit_status_msg
|
||||
|
||||
This workflow attempts to automatically fix TypeScript compatibility issues that may arise from npm audit fixes.
|
||||
|
||||
⚠️ **Manual Review Required**: The build is currently failing after automated fixes were attempted.
|
||||
|
||||
Common issues and solutions:
|
||||
- Check for TypeScript version compatibility with Node.js types
|
||||
- Review breaking changes in updated dependencies
|
||||
- Consider pinning problematic dependency versions temporarily
|
||||
- Review tsconfig.json for compatibility settings
|
||||
|
||||
**Automated Fix Strategy**:
|
||||
1. Run npm audit fix with proper error handling
|
||||
2. Update @types/node to latest compatible version
|
||||
3. Try Node 20 specific @types/node version if needed
|
||||
4. Clean reinstall dependencies if conflicts persist
|
||||
5. Update TypeScript compiler if necessary
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [NPM Audit Fix with TypeScript Auto-Fix Workflow](https://github.com/actions/runner/blob/main/.github/workflows/npm-audit-ts-fix.yml)
|
||||
EOF
|
||||
else
|
||||
cat > pr_body.txt << EOF
|
||||
Automated npm audit fix with TypeScript auto-repair for hashFiles dependencies.
|
||||
|
||||
**Build Status**: ✅ Build passes
|
||||
$audit_status_msg
|
||||
|
||||
This workflow attempts to automatically fix TypeScript compatibility issues that may arise from npm audit fixes.
|
||||
|
||||
✅ **Ready to Merge**: All automated fixes were successful and the build passes.
|
||||
|
||||
**Automated Fix Strategy**:
|
||||
1. Run npm audit fix with proper error handling
|
||||
2. Update @types/node to latest compatible version
|
||||
3. Try Node 20 specific @types/node version if needed
|
||||
4. Clean reinstall dependencies if conflicts persist
|
||||
5. Update TypeScript compiler if necessary
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [NPM Audit Fix with TypeScript Auto-Fix Workflow](https://github.com/actions/runner/blob/main/.github/workflows/npm-audit-ts-fix.yml)
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ -n "$fixes_applied" ]; then
|
||||
# Add the fixes applied section to the file
|
||||
sed -i "/This workflow attempts/a\\
|
||||
\\
|
||||
**Automated Fixes Applied**:$fixes_applied" pr_body.txt
|
||||
fi
|
||||
|
||||
# Create PR with appropriate labels
|
||||
labels="dependencies,dependencies-not-dependabot,typescript,npm,security"
|
||||
if [[ "$build_status" == *"fails"* ]]; then
|
||||
labels="dependencies,dependencies-not-dependabot,typescript,npm,security,needs-manual-review"
|
||||
fi
|
||||
|
||||
# Create PR
|
||||
gh pr create -B main -H "$branch_name" \
|
||||
--title "chore: npm audit fix with TypeScript auto-repair" \
|
||||
--label "$labels" \
|
||||
--body-file pr_body.txt
|
||||
else
|
||||
echo "No changes to commit"
|
||||
fi
|
||||
137
.github/workflows/npm-audit.yml
vendored
137
.github/workflows/npm-audit.yml
vendored
@@ -1,137 +0,0 @@
|
||||
name: NPM Audit Fix
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 7 * * 1" # Weekly on Monday at 7 AM UTC
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
npm-audit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- name: NPM install and audit fix
|
||||
working-directory: src/Misc/expressionFunc/hashFiles
|
||||
run: |
|
||||
npm install
|
||||
|
||||
# Check what vulnerabilities exist
|
||||
echo "=== Checking current vulnerabilities ==="
|
||||
npm audit || true
|
||||
|
||||
# Apply audit fix --force to get security updates
|
||||
echo "=== Applying npm audit fix --force ==="
|
||||
npm audit fix --force
|
||||
|
||||
# Test if build still works and set status
|
||||
echo "=== Testing build compatibility ==="
|
||||
if npm run all; then
|
||||
echo "✅ Build successful after audit fix"
|
||||
echo "AUDIT_FIX_STATUS=success" >> $GITHUB_ENV
|
||||
else
|
||||
echo "❌ Build failed after audit fix - will create PR with fix instructions"
|
||||
echo "AUDIT_FIX_STATUS=build_failed" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Create PR if changes exist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# Check if there are any changes
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
# Configure git
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Create branch and commit changes
|
||||
branch_name="chore/npm-audit-fix-$(date +%Y%m%d)"
|
||||
git checkout -b "$branch_name"
|
||||
git add .
|
||||
git commit -m "chore: npm audit fix for hashFiles dependencies" --no-verify
|
||||
git push origin "$branch_name"
|
||||
|
||||
# Create PR body based on what actually happened
|
||||
if [ "$AUDIT_FIX_STATUS" = "success" ]; then
|
||||
cat > pr_body.txt << 'EOF'
|
||||
Automated npm audit fix for security vulnerabilities in hashFiles dependencies.
|
||||
|
||||
**✅ Full Fix Applied Successfully**
|
||||
This update addresses npm security advisories and ensures dependencies are secure and up-to-date.
|
||||
|
||||
**Changes made:**
|
||||
- Applied `npm audit fix --force` to resolve security vulnerabilities
|
||||
- Updated package-lock.json with security patches
|
||||
- Verified build compatibility with `npm run all`
|
||||
|
||||
**Next steps:**
|
||||
- Review the dependency changes
|
||||
- Verify the hashFiles functionality still works as expected
|
||||
- Merge when ready
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [NPM Audit Fix Workflow](https://github.com/actions/runner/blob/main/.github/workflows/npm-audit.yml)
|
||||
EOF
|
||||
elif [ "$AUDIT_FIX_STATUS" = "build_failed" ]; then
|
||||
cat > pr_body.txt << 'EOF'
|
||||
Automated npm audit fix for security vulnerabilities in hashFiles dependencies.
|
||||
|
||||
**⚠️ Security Fixes Applied - Build Issues Need Manual Resolution**
|
||||
This update applies important security patches but causes build failures that require manual fixes.
|
||||
|
||||
**Changes made:**
|
||||
- Applied `npm audit fix --force` to resolve security vulnerabilities
|
||||
- Updated package-lock.json with security patches
|
||||
|
||||
**⚠️ Build Issues Detected:**
|
||||
The build fails after applying security fixes, likely due to TypeScript compatibility issues with updated `@types/node`.
|
||||
|
||||
**Required Manual Fixes:**
|
||||
1. Review TypeScript compilation errors in the build output
|
||||
2. Update TypeScript configuration if needed
|
||||
3. Consider pinning `@types/node` to a compatible version
|
||||
4. Run `npm run all` locally to verify fixes
|
||||
|
||||
**Next steps:**
|
||||
- **DO NOT merge until build issues are resolved**
|
||||
- Apply manual fixes for TypeScript compatibility
|
||||
- Test the hashFiles functionality still works as expected
|
||||
- Merge when build passes
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [NPM Audit Fix Workflow](https://github.com/actions/runner/blob/main/.github/workflows/npm-audit.yml)
|
||||
EOF
|
||||
else
|
||||
# Fallback case
|
||||
cat > pr_body.txt << 'EOF'
|
||||
Automated npm audit attempted for security vulnerabilities in hashFiles dependencies.
|
||||
|
||||
**ℹ️ No Changes Applied**
|
||||
No security vulnerabilities were found or no changes were needed.
|
||||
|
||||
---
|
||||
|
||||
Autogenerated by [NPM Audit Fix Workflow](https://github.com/actions/runner/blob/main/.github/workflows/npm-audit.yml)
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Create PR
|
||||
gh pr create -B main -H "$branch_name" \
|
||||
--title "chore: npm audit fix for hashFiles dependencies" \
|
||||
--label "dependencies" \
|
||||
--label "dependencies-weekly-check" \
|
||||
--label "dependencies-not-dependabot" \
|
||||
--label "npm" \
|
||||
--label "typescript" \
|
||||
--label "security" \
|
||||
--body-file pr_body.txt
|
||||
else
|
||||
echo "✅ No changes to commit - npm audit fix did not modify any files"
|
||||
fi
|
||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
# Make sure ./releaseVersion match ./src/runnerversion
|
||||
# Query GitHub release ensure version is not used
|
||||
- name: Check version
|
||||
uses: actions/github-script@v8.0.0
|
||||
uses: actions/github-script@v7.0.1
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
@@ -171,7 +171,7 @@ jobs:
|
||||
# Create ReleaseNote file
|
||||
- name: Create ReleaseNote
|
||||
id: releaseNote
|
||||
uses: actions/github-script@v8.0.0
|
||||
uses: actions/github-script@v7.0.1
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
@@ -300,7 +300,7 @@ jobs:
|
||||
|
||||
- name: Compute image version
|
||||
id: image
|
||||
uses: actions/github-script@v8.0.0
|
||||
uses: actions/github-script@v7.0.1
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
@@ -338,7 +338,7 @@ jobs:
|
||||
org.opencontainers.image.licenses=MIT
|
||||
|
||||
- name: Generate attestation
|
||||
uses: actions/attest-build-provenance@v3
|
||||
uses: actions/attest-build-provenance@v2
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||
|
||||
2
.github/workflows/stale-bot.yml
vendored
2
.github/workflows/stale-bot.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
stale-issue-message: "This issue is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 15 days."
|
||||
close-issue-message: "This issue was closed because it has been stalled for 15 days with no activity."
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
cd src/Misc/expressionFunc/hashFiles && npx lint-staged
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
cd src/Misc/expressionFunc/hashFiles
|
||||
|
||||
npx lint-staged
|
||||
|
||||
31
README.md
31
README.md
@@ -12,28 +12,33 @@ The runner is the application that runs a job from a GitHub Actions workflow. It
|
||||
|
||||
For more information about installing and using self-hosted runners, see [Adding self-hosted runners](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/adding-self-hosted-runners) and [Using self-hosted runners in a workflow](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-self-hosted-runners-in-a-workflow)
|
||||
|
||||
Runner releases:
|
||||
## Download and Install
|
||||
|
||||
 [Pre-reqs](docs/start/envwin.md) | [Download](https://github.com/actions/runner/releases)
|
||||
 **Windows**: [Prerequisites](docs/start/envwin.md) | [Download](https://github.com/actions/runner/releases)
|
||||
|
||||
 [Pre-reqs](docs/start/envosx.md) | [Download](https://github.com/actions/runner/releases)
|
||||
 **macOS**: [Prerequisites](docs/start/envosx.md) | [Download](https://github.com/actions/runner/releases)
|
||||
|
||||
 [Pre-reqs](docs/start/envlinux.md) | [Download](https://github.com/actions/runner/releases)
|
||||
 **Linux**: [Prerequisites](docs/start/envlinux.md) | [Download](https://github.com/actions/runner/releases)
|
||||
|
||||
### Note
|
||||
## Documentation and Resources
|
||||
|
||||
Thank you for your interest in this GitHub repo, however, right now we are not taking contributions.
|
||||
- 📚 **[Complete Documentation Index](docs/README.md)** - Comprehensive guide to all documentation
|
||||
- 📖 **[Contributing Guide](docs/contribute.md)** - Development setup, building, and testing
|
||||
- 🔧 **[Automation Scripts](docs/automate.md)** - Automate runner setup and configuration
|
||||
- 🛠️ **[Troubleshooting Guides](docs/checks/README.md)** - Common issues and solutions
|
||||
- 🏗️ **[Architecture Decision Records](docs/adrs/README.md)** - Important architectural decisions
|
||||
- ⚙️ **Platform Prerequisites:** [Linux](docs/start/envlinux.md) | [Windows](docs/start/envwin.md) | [macOS](docs/start/envosx.md)
|
||||
|
||||
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in.
|
||||
## Support and Community
|
||||
|
||||
We are taking the following steps to better direct requests related to GitHub Actions, including:
|
||||
Thank you for your interest in this repository. Please note our current contribution and support guidelines:
|
||||
|
||||
1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions)
|
||||
**Bug Reports:** You are welcome to report bugs in this repository through Issues.
|
||||
|
||||
2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report.
|
||||
**Feature Requests:** Please submit feature and enhancement requests on the [GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions) page.
|
||||
|
||||
3. Security Issues should be handled as per our [security.md](security.md)
|
||||
**Support Questions:** For help and support, please use our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions).
|
||||
|
||||
We will still provide security updates for this project and fix major breaking changes during this time.
|
||||
**Security Issues:** Please report security vulnerabilities following our [security policy](security.md).
|
||||
|
||||
You are welcome to still raise bugs in this repo.
|
||||
**High Priority Issues:** Critical bugs can be reported through Community Discussions or our [support team](https://support.github.com/contact/bug-report).
|
||||
61
docs/README.md
Normal file
61
docs/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# GitHub Actions Runner Documentation
|
||||
|
||||
Welcome to the GitHub Actions Runner documentation. This guide will help you get started with self-hosted runners, contribute to the project, and troubleshoot common issues.
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
### Installation and Setup
|
||||
- **[Linux Prerequisites](start/envlinux.md)** - Complete setup guide for Linux systems
|
||||
- **[Windows Prerequisites](start/envwin.md)** - Complete setup guide for Windows systems
|
||||
- **[macOS Prerequisites](start/envosx.md)** - Complete setup guide for macOS systems
|
||||
|
||||
### Quick Start
|
||||
1. Download the [latest runner release](https://github.com/actions/runner/releases)
|
||||
2. Follow the platform-specific prerequisites guide above
|
||||
3. Configure your runner with `./config.sh` (Linux/macOS) or `.\config.cmd` (Windows)
|
||||
4. Start the runner with `./run.sh` (Linux/macOS) or `.\run.cmd` (Windows)
|
||||
|
||||
## 🔧 Administration and Automation
|
||||
|
||||
- **[Automation Scripts](automate.md)** - Automate runner deployment and management
|
||||
- **[Troubleshooting Guides](checks/)** - Common issues and solutions
|
||||
|
||||
## 🏗️ Development and Contributing
|
||||
|
||||
- **[Contributing Guide](contribute.md)** - Development setup, building, and testing
|
||||
- **[Architecture Decision Records](adrs/README.md)** - Important architectural decisions and design patterns
|
||||
|
||||
## 📋 Reference Materials
|
||||
|
||||
### System Checks and Troubleshooting
|
||||
- **[Network Connectivity](checks/network.md)** - Troubleshoot network issues
|
||||
- **[Git Configuration](checks/git.md)** - Git-related problems
|
||||
- **[Actions Troubleshooting](checks/actions.md)** - Action-specific issues
|
||||
- **[SSL Certificate Issues](checks/sslcert.md)** - Certificate and TLS problems
|
||||
- **[Node.js Issues](checks/nodejs.md)** - Node.js runtime problems
|
||||
- **[Internet Connectivity](checks/internet.md)** - General connectivity issues
|
||||
|
||||
### Development Resources
|
||||
- **[Visual Studio Code Setup](contribute/vscode.md)** - IDE configuration for development
|
||||
- **[Design Documentation](design/)** - Technical design documents
|
||||
|
||||
## 🆘 Getting Help
|
||||
|
||||
### Community Support
|
||||
- **[GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions)** - Ask questions and get help from the community
|
||||
- **[GitHub Support](https://support.github.com/contact/bug-report)** - Report critical bugs or get professional support
|
||||
|
||||
### Reporting Issues
|
||||
- **Bug Reports**: Open an issue in this repository
|
||||
- **Feature Requests**: Use [GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions-and-packages)
|
||||
- **Security Issues**: Follow our [security policy](../security.md)
|
||||
|
||||
## 📖 Additional Resources
|
||||
|
||||
- **[GitHub Actions Documentation](https://docs.github.com/en/actions)** - Official GitHub Actions documentation
|
||||
- **[Self-hosted Runners Guide](https://docs.github.com/en/actions/hosting-your-own-runners)** - GitHub's official self-hosted runner documentation
|
||||
- **[Runner Releases](https://github.com/actions/runner/releases)** - Download the latest runner versions
|
||||
|
||||
---
|
||||
|
||||
> **Note**: This documentation is maintained by the GitHub Actions team and the community. If you find any issues or have suggestions for improvement, please open an issue or contribute a pull request.
|
||||
@@ -76,3 +76,76 @@ Repo level one-liner. NOTE: replace with yourorg/yourrepo (repo level) or just
|
||||
```bash
|
||||
curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/delete.sh | bash -s yourorg/yourrepo runnername
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Permission Denied
|
||||
```bash
|
||||
# Ensure scripts have execute permissions
|
||||
chmod +x ./config.sh ./run.sh
|
||||
```
|
||||
|
||||
#### PAT Token Issues
|
||||
```bash
|
||||
# Verify your PAT has the correct scopes:
|
||||
# - repo (for repository-level runners)
|
||||
# - admin:org (for organization-level runners)
|
||||
export RUNNER_CFG_PAT=your_token_here
|
||||
echo $RUNNER_CFG_PAT # Verify it's set
|
||||
```
|
||||
|
||||
#### Network Connectivity
|
||||
```bash
|
||||
# Test GitHub connectivity
|
||||
curl -H "Authorization: token $RUNNER_CFG_PAT" https://api.github.com/user
|
||||
|
||||
# For GitHub Enterprise Server
|
||||
curl -H "Authorization: token $RUNNER_CFG_PAT" https://your-github-enterprise/api/v3/user
|
||||
```
|
||||
|
||||
#### Service Installation Fails
|
||||
```bash
|
||||
# Check if running as appropriate user
|
||||
whoami
|
||||
|
||||
# For Linux - ensure systemd is available
|
||||
systemctl --version
|
||||
|
||||
# For macOS - ensure launchd is available
|
||||
launchctl version
|
||||
```
|
||||
|
||||
#### Runner Registration Fails
|
||||
```bash
|
||||
# Check if runner already exists
|
||||
curl -H "Authorization: token $RUNNER_CFG_PAT" \
|
||||
"https://api.github.com/repos/OWNER/REPO/actions/runners"
|
||||
|
||||
# Remove existing runner if needed
|
||||
./config.sh remove --token $RUNNER_CFG_PAT
|
||||
```
|
||||
|
||||
### Getting Help
|
||||
|
||||
- **Configuration Issues**: Check the [Prerequisites](start/envlinux.md) for your platform
|
||||
- **Network Problems**: Review [network troubleshooting guide](checks/network.md)
|
||||
- **General Support**: Visit [GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions)
|
||||
|
||||
### Advanced Examples
|
||||
|
||||
#### Organization-level Runner with Custom Labels
|
||||
```bash
|
||||
export RUNNER_CFG_PAT=your_org_pat
|
||||
curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/create-latest-svc.sh | \
|
||||
bash -s -- -s myorg -n prod-runner-1 -l production,linux,docker
|
||||
```
|
||||
|
||||
#### Repository-level Runner for GitHub Enterprise
|
||||
```bash
|
||||
export RUNNER_CFG_PAT=your_ghe_pat
|
||||
curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/create-latest-svc.sh | \
|
||||
bash -s -- -s myorg/myrepo -g github.company.com -n build-server -u builder
|
||||
```
|
||||
```
|
||||
|
||||
66
docs/checks/README.md
Normal file
66
docs/checks/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Troubleshooting Guides
|
||||
|
||||
This directory contains troubleshooting guides for common issues you might encounter when setting up or running GitHub Actions self-hosted runners.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Issue Type | Guide | Description |
|
||||
|------------|-------|-------------|
|
||||
| 🌐 **Network** | [network.md](network.md) | Connection issues, proxy, firewall problems |
|
||||
| 🔒 **SSL/TLS** | [sslcert.md](sslcert.md) | Certificate and TLS handshake issues |
|
||||
| 📦 **Git** | [git.md](git.md) | Git configuration and repository access |
|
||||
| ⚡ **Actions** | [actions.md](actions.md) | Action-specific runtime issues |
|
||||
| 🟢 **Node.js** | [nodejs.md](nodejs.md) | Node.js runtime and npm issues |
|
||||
| 🌍 **Internet** | [internet.md](internet.md) | General internet connectivity |
|
||||
|
||||
## Common First Steps
|
||||
|
||||
Before diving into specific guides, try these general troubleshooting steps:
|
||||
|
||||
### 1. Check Basic Connectivity
|
||||
```bash
|
||||
# Test GitHub API access
|
||||
curl -I https://api.github.com/
|
||||
|
||||
# For GitHub Enterprise Server
|
||||
curl -I https://your-github-enterprise.com/api/v3/
|
||||
```
|
||||
|
||||
### 2. Verify Runner Status
|
||||
```bash
|
||||
# Check if runner service is running
|
||||
./svc.sh status
|
||||
|
||||
# View recent logs
|
||||
tail -f _diag/Runner_*.log
|
||||
```
|
||||
|
||||
### 3. Test Runner Configuration
|
||||
```bash
|
||||
# Re-run configuration
|
||||
./config.sh
|
||||
|
||||
# Test connection without running
|
||||
./run.sh --check
|
||||
```
|
||||
|
||||
## Getting Additional Help
|
||||
|
||||
If these guides don't resolve your issue:
|
||||
|
||||
1. **Search existing issues** in the [runner repository](https://github.com/actions/runner/issues)
|
||||
2. **Check GitHub Status** at [githubstatus.com](https://githubstatus.com)
|
||||
3. **Ask the community** in [GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions)
|
||||
4. **Contact support** for critical issues via [GitHub Support](https://support.github.com/contact)
|
||||
|
||||
## Contributing
|
||||
|
||||
Found a solution to a common problem not covered here? Consider contributing:
|
||||
|
||||
1. Create a new `.md` file for the issue type
|
||||
2. Follow the format of existing guides
|
||||
3. Submit a pull request with your improvements
|
||||
|
||||
---
|
||||
|
||||
💡 **Tip**: Always check the `_diag/` directory for detailed log files when troubleshooting issues.
|
||||
@@ -1,5 +1,24 @@
|
||||
# Contributions
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Getting Started](#getting-started)
|
||||
- [Issues](#issues)
|
||||
- [Enhancements and Feature Requests](#enhancements-and-feature-requests)
|
||||
- [Required Dev Dependencies](#required-dev-dependencies)
|
||||
- [Quickstart: Run a Job from a Real Repository](#quickstart-run-a-job-from-a-real-repository)
|
||||
- [Development Life Cycle](#development-life-cycle)
|
||||
- [Clone Repository](#clone-repository)
|
||||
- [Build Layout](#build-layout)
|
||||
- [Test Layout](#test-layout)
|
||||
- [Configure Runner](#configure-runner)
|
||||
- [Run Runner](#run-runner)
|
||||
- [View Logs](#view-logs)
|
||||
- [Editors](#editors)
|
||||
- [Styling](#styling)
|
||||
|
||||
## Getting Started
|
||||
|
||||
We welcome contributions in the form of issues and pull requests. We view the contributions and the process as the same for github and external contributors. Please note the runner typically requires changes across the entire system and we aim for issues in the runner to be entirely self contained and fixable here. Therefore, we will primarily handle bug issues opened in this repo and we kindly request you to create all feature and enhancement requests on the [GitHub Feedback](https://github.com/community/community/discussions/categories/actions-and-packages) page.
|
||||
|
||||
> IMPORTANT: Building your own runner is critical for the dev inner loop process when contributing changes. However, only runners built and distributed by GitHub (releases) are supported in production. Be aware that workflows and orchestrations run service side with the runner being a remote process to run steps. For that reason, the service can pull the runner forward so customizations can be lost.
|
||||
@@ -124,8 +143,8 @@ cd runner/_layout
|
||||
./config.(sh/cmd) # configure your custom runner
|
||||
```
|
||||
|
||||
You will need your the name of your repository and a runner registration token.
|
||||
Check [Quickstart](##Quickstart:-Run-a-job-from-a-real-repository) if you don't know how to get this token.
|
||||
You will need the name of your repository and a runner registration token.
|
||||
Check the [Quickstart section](#quickstart-run-a-job-from-a-real-repository) if you don't know how to get this token.
|
||||
|
||||
These can also be passed down as arguments to `config.(sh/cmd)`:
|
||||
```bash
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
# Runner Dependency Management Process
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the automated dependency management process for the GitHub Actions Runner, designed to ensure we maintain up-to-date and secure dependencies while providing predictable release cycles.
|
||||
|
||||
## Release Schedule
|
||||
|
||||
- **Monthly Runner Releases**: New runner versions are released monthly
|
||||
- **Weekly Dependency Checks**: Automated workflows check for dependency updates every Monday
|
||||
- **Security Patches**: Critical security vulnerabilities are addressed immediately outside the regular schedule
|
||||
|
||||
## Automated Workflows
|
||||
|
||||
**Note**: These workflows are implemented across separate PRs for easier review and independent deployment. Each workflow includes comprehensive error handling and security-focused vulnerability detection.
|
||||
|
||||
### 1. Foundation Labels
|
||||
|
||||
- **Workflow**: `.github/workflows/setup-labels.yml` (PR #4024)
|
||||
- **Purpose**: Creates consistent dependency labels for all automation workflows
|
||||
- **Labels**: `dependencies`, `security`, `typescript`, `needs-manual-review`
|
||||
- **Prerequisite**: Must be merged before other workflows for proper labeling
|
||||
|
||||
### 2. Node.js Version Updates
|
||||
|
||||
- **Workflow**: `.github/workflows/node-upgrade.yml`
|
||||
- **Schedule**: Mondays at 6:00 AM UTC
|
||||
- **Purpose**: Updates Node.js 20 and 24 versions in `src/Misc/externals.sh`
|
||||
- **Source**: [nodejs.org](https://nodejs.org) and [actions/alpine_nodejs](https://github.com/actions/alpine_nodejs)
|
||||
- **Priority**: First (NPM depends on current Node.js versions)
|
||||
|
||||
### 3. NPM Security Audit
|
||||
|
||||
- **Primary Workflow**: `.github/workflows/npm-audit.yml` ("NPM Audit Fix")
|
||||
- **Schedule**: Mondays at 7:00 AM UTC
|
||||
- **Purpose**: Automated security vulnerability detection and basic fixes
|
||||
- **Location**: `src/Misc/expressionFunc/hashFiles/`
|
||||
- **Features**: npm audit, security patch application, PR creation
|
||||
- **Dependency**: Runs after Node.js updates for optimal compatibility
|
||||
|
||||
- **Fallback Workflow**: `.github/workflows/npm-audit-typescript.yml` ("NPM Audit Fix with TypeScript Auto-Fix")
|
||||
- **Trigger**: Manual dispatch only
|
||||
- **Purpose**: Manual security audit with TypeScript compatibility fixes
|
||||
- **Use Case**: When scheduled workflow fails or needs custom intervention
|
||||
- **Features**: Enhanced TypeScript auto-repair, graduated security response
|
||||
- **How to Use**:
|
||||
1. If the scheduled "NPM Audit Fix" workflow fails, go to Actions tab
|
||||
2. Select "NPM Audit Fix with TypeScript Auto-Fix" workflow
|
||||
3. Click "Run workflow" and optionally specify fix level (auto/manual)
|
||||
4. Review the generated PR for TypeScript compatibility issues
|
||||
|
||||
### 4. .NET SDK Updates
|
||||
|
||||
- **Workflow**: `.github/workflows/dotnet-upgrade.yml`
|
||||
- **Schedule**: Mondays at midnight UTC
|
||||
- **Purpose**: Updates .NET SDK and package versions with build validation
|
||||
- **Features**: Global.json updates, NuGet package management, compatibility checking
|
||||
- **Independence**: Runs independently of Node.js/NPM updates
|
||||
|
||||
### 5. Docker/Buildx Updates
|
||||
|
||||
- **Workflow**: `.github/workflows/docker-buildx-upgrade.yml` ("Docker/Buildx Version Upgrade")
|
||||
- **Schedule**: Mondays at midnight UTC
|
||||
- **Purpose**: Updates Docker and Docker Buildx versions with multi-platform validation
|
||||
- **Features**: Container security scanning, multi-architecture build testing
|
||||
- **Independence**: Runs independently of other dependency updates
|
||||
|
||||
### 6. Dependency Monitoring
|
||||
|
||||
- **Workflow**: `.github/workflows/dependency-check.yml` ("Dependency Status Check")
|
||||
- **Schedule**: Mondays at 11:00 AM UTC
|
||||
- **Purpose**: Comprehensive status report of all dependencies with security audit
|
||||
- **Features**: Multi-dependency checking, npm audit status, build validation, choice of specific component checks
|
||||
- **Summary**: Runs last to capture results from all morning dependency updates
|
||||
|
||||
## Release Process Integration
|
||||
|
||||
### Pre-Release Checklist
|
||||
|
||||
Before each monthly runner release:
|
||||
|
||||
1. **Check Dependency PRs**:
|
||||
|
||||
```bash
|
||||
# List all open dependency PRs
|
||||
gh pr list --label "dependencies" --state open
|
||||
|
||||
# List only automated weekly dependency updates
|
||||
gh pr list --label "dependencies-weekly-check" --state open
|
||||
|
||||
# List only custom dependency automation (not dependabot)
|
||||
gh pr list --label "dependencies-not-dependabot" --state open
|
||||
```
|
||||
|
||||
2. **Run Manual Dependency Check**:
|
||||
- Go to Actions tab → "Dependency Status Check" → "Run workflow"
|
||||
- Review the summary for any outdated dependencies
|
||||
|
||||
3. **Review and Merge Updates**:
|
||||
- Prioritize security-related updates
|
||||
- Test dependency updates in development environment
|
||||
- Merge approved dependency PRs
|
||||
|
||||
### Vulnerability Response
|
||||
|
||||
#### Critical Security Vulnerabilities
|
||||
|
||||
- **Response Time**: Within 24 hours
|
||||
- **Process**:
|
||||
1. Assess impact on runner security
|
||||
2. Create hotfix branch if runner data security is affected
|
||||
3. Expedite patch release if necessary
|
||||
4. Document in security advisory if applicable
|
||||
|
||||
#### Non-Critical Vulnerabilities
|
||||
|
||||
- **Response Time**: Next monthly release
|
||||
- **Process**:
|
||||
1. Evaluate if vulnerability affects runner functionality
|
||||
2. Include fix in regular dependency update cycle
|
||||
3. Document in release notes
|
||||
|
||||
## Monitoring and Alerts
|
||||
|
||||
### GitHub Actions Workflow Status
|
||||
|
||||
- All dependency workflows create PRs with the `dependencies` label
|
||||
- Failed workflows should be investigated immediately
|
||||
- Weekly dependency status reports are generated automatically
|
||||
|
||||
### Manual Checks
|
||||
|
||||
You can manually trigger dependency checks:
|
||||
|
||||
- **Full Status**: Run "Dependency Status Check" workflow
|
||||
- **Specific Component**: Use the dropdown to check individual dependencies
|
||||
|
||||
## Dependency Labels
|
||||
|
||||
All automated dependency PRs are tagged with labels for easy filtering and management:
|
||||
|
||||
### Primary Labels
|
||||
|
||||
- **`dependencies`**: All automated dependency-related PRs
|
||||
- **`dependencies-weekly-check`**: Automated weekly dependency updates from scheduled workflows
|
||||
- **`dependencies-not-dependabot`**: Custom dependency automation (not created by dependabot)
|
||||
- **`security`**: Security vulnerability fixes and patches
|
||||
- **`typescript`**: TypeScript compatibility and type definition updates
|
||||
- **`needs-manual-review`**: Complex updates requiring human verification
|
||||
|
||||
### Technology-Specific Labels
|
||||
|
||||
- **`node`**: Node.js version updates
|
||||
- **`javascript`**: JavaScript runtime and tooling updates
|
||||
- **`npm`**: NPM package and security updates
|
||||
- **`dotnet`**: .NET SDK and NuGet package updates
|
||||
- **`docker`**: Docker and container tooling updates
|
||||
|
||||
### Workflow-Specific Branches
|
||||
|
||||
- **Node.js updates**: `chore/update-node` branch
|
||||
- **NPM security fixes**: `chore/npm-audit-fix-YYYYMMDD` and `chore/npm-audit-fix-with-ts-repair` branches
|
||||
- **NuGet/.NET updates**: `feature/dotnetsdk-upgrade/{version}` branches
|
||||
- **Docker updates**: `feature/docker-buildx-upgrade` branch
|
||||
|
||||
## Special Considerations
|
||||
|
||||
### Node.js Updates
|
||||
|
||||
When updating Node.js versions, remember to:
|
||||
|
||||
1. Create a corresponding release in [actions/alpine_nodejs](https://github.com/actions/alpine_nodejs)
|
||||
2. Follow the alpine_nodejs getting started guide
|
||||
3. Test container builds with new Node versions
|
||||
|
||||
### .NET SDK Updates
|
||||
|
||||
- Only patch versions are auto-updated within the same major.minor version
|
||||
- Major/minor version updates require manual review and testing
|
||||
|
||||
### Docker Updates
|
||||
|
||||
- Updates include both Docker Engine and Docker Buildx
|
||||
- Verify compatibility with runner container workflows
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **NPM Audit Workflow Fails**:
|
||||
- Check if `package.json` exists in `src/Misc/expressionFunc/hashFiles/`
|
||||
- Verify Node.js setup step succeeded
|
||||
|
||||
2. **Version Detection Fails**:
|
||||
- Check if upstream APIs are available
|
||||
- Verify parsing logic for version extraction
|
||||
|
||||
3. **PR Creation Fails**:
|
||||
- Ensure `GITHUB_TOKEN` has sufficient permissions
|
||||
- Check if branch already exists
|
||||
|
||||
### Contact
|
||||
|
||||
For questions about the dependency management process:
|
||||
|
||||
- Create an issue with the `dependencies` label
|
||||
- Review existing dependency management workflows
|
||||
- Consult the runner team for security-related concerns
|
||||
|
||||
## Metrics and KPIs
|
||||
|
||||
Track these metrics to measure dependency management effectiveness:
|
||||
|
||||
- Number of open dependency PRs at release time
|
||||
- Time to merge dependency updates
|
||||
- Number of security vulnerabilities by severity
|
||||
- Release cycle adherence (monthly target)
|
||||
@@ -6,10 +6,21 @@
|
||||
|
||||
Please see "[Supported architectures and operating systems for self-hosted runners](https://docs.github.com/en/actions/reference/runners/self-hosted-runners#linux)."
|
||||
|
||||
## Install .Net Core 3.x Linux Dependencies
|
||||
## Quick Setup
|
||||
|
||||
The `./config.sh` script will automatically check and guide you through installing .NET dependencies:
|
||||
|
||||
```bash
|
||||
./config.sh
|
||||
# If dependencies are missing, run:
|
||||
./bin/installdependencies.sh
|
||||
```
|
||||
|
||||
## Install .NET Core Linux Dependencies
|
||||
|
||||
The `./config.sh` will check .NET Core dependencies during runner configuration.
|
||||
You might see something like this which indicates a dependency is missing:
|
||||
|
||||
The `./config.sh` will check .Net Core 3.x dependencies during runner configuration.
|
||||
You might see something like this which indicate a dependency's missing.
|
||||
```bash
|
||||
./config.sh
|
||||
libunwind.so.8 => not found
|
||||
@@ -17,34 +28,87 @@ You might see something like this which indicate a dependency's missing.
|
||||
Dependencies is missing for Dotnet Core 6.0
|
||||
Execute ./bin/installdependencies.sh to install any missing Dotnet Core 6.0 dependencies.
|
||||
```
|
||||
|
||||
You can easily correct the problem by executing `./bin/installdependencies.sh`.
|
||||
The `installdependencies.sh` script should install all required dependencies on all supported Linux versions
|
||||
> Note: The `installdependencies.sh` script will try to use the default package management mechanism on your Linux flavor (ex. `yum`/`apt-get`/`apt`).
|
||||
|
||||
### Full dependencies list
|
||||
> **Note:** The `installdependencies.sh` script will try to use the default package management mechanism on your Linux flavor (ex. `yum`/`apt-get`/`apt`).
|
||||
|
||||
Debian based OS (Debian, Ubuntu, Linux Mint)
|
||||
## Manual Dependency Installation
|
||||
|
||||
If the automatic installation doesn't work, you can manually install dependencies using your package manager:
|
||||
|
||||
### Debian based OS (Debian, Ubuntu, Linux Mint)
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y liblttng-ust1 libkrb5-3 zlib1g libssl1.1 libicu66
|
||||
```
|
||||
|
||||
**Required packages:**
|
||||
- liblttng-ust1 or liblttng-ust0
|
||||
- libkrb5-3
|
||||
- zlib1g
|
||||
- libssl1.1, libssl1.0.2 or libssl1.0.0
|
||||
- libicu63, libicu60, libicu57 or libicu55
|
||||
|
||||
Fedora based OS (Fedora, Red Hat Enterprise Linux, CentOS, Oracle Linux 7)
|
||||
### Fedora based OS (Fedora, Red Hat Enterprise Linux, CentOS, Oracle Linux 7)
|
||||
|
||||
```bash
|
||||
sudo yum install -y lttng-ust openssl-libs krb5-libs zlib libicu
|
||||
# Or for newer systems:
|
||||
sudo dnf install -y lttng-ust openssl-libs krb5-libs zlib libicu
|
||||
```
|
||||
|
||||
**Required packages:**
|
||||
- lttng-ust
|
||||
- openssl-libs
|
||||
- krb5-libs
|
||||
- zlib
|
||||
- libicu
|
||||
|
||||
SUSE based OS (OpenSUSE, SUSE Enterprise)
|
||||
### SUSE based OS (OpenSUSE, SUSE Enterprise)
|
||||
|
||||
```bash
|
||||
sudo zypper install -y lttng-ust libopenssl1_1 krb5 zlib libicu60_2
|
||||
```
|
||||
|
||||
**Required packages:**
|
||||
- lttng-ust
|
||||
- libopenssl1_1
|
||||
- krb5
|
||||
- zlib
|
||||
- libicu60_2
|
||||
|
||||
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x)
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Permission denied errors:**
|
||||
```bash
|
||||
sudo chmod +x ./config.sh ./run.sh
|
||||
```
|
||||
|
||||
**Missing dependencies after installation:**
|
||||
```bash
|
||||
# Check what's missing
|
||||
ldd ./bin/Runner.Listener
|
||||
# Reinstall dependencies
|
||||
./bin/installdependencies.sh
|
||||
```
|
||||
|
||||
**SSL/TLS errors:**
|
||||
```bash
|
||||
# Update certificates
|
||||
sudo apt-get update && sudo apt-get install ca-certificates
|
||||
# Or for RHEL/CentOS:
|
||||
sudo yum update ca-certificates
|
||||
```
|
||||
|
||||
### Getting Help
|
||||
|
||||
- Check our [troubleshooting guide](../checks/README.md)
|
||||
- Search [GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions)
|
||||
- Review [common network issues](../checks/network.md)
|
||||
|
||||
## [More .NET Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x)
|
||||
|
||||
@@ -1,9 +1,136 @@
|
||||
|
||||
|
||||
#  macOS/OS X System Prerequisites
|
||||
#  macOS System Prerequisites
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Please see "[Supported architectures and operating systems for self-hosted runners](https://docs.github.com/en/actions/reference/runners/self-hosted-runners#macos)."
|
||||
|
||||
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore30)
|
||||
## Quick Setup
|
||||
|
||||
1. **Download** the latest runner from [releases](https://github.com/actions/runner/releases)
|
||||
2. **Extract** the downloaded archive: `tar xzf actions-runner-osx-x64-*.tar.gz`
|
||||
3. **Run** `./config.sh` to configure the runner
|
||||
4. **Install** as a service: `sudo ./svc.sh install` and `sudo ./svc.sh start`
|
||||
|
||||
## System Requirements
|
||||
|
||||
### macOS Version
|
||||
- macOS 10.15 (Catalina) or later
|
||||
- Both Intel (x64) and Apple Silicon (ARM64) are supported
|
||||
|
||||
### Required Tools
|
||||
|
||||
#### Homebrew (Recommended)
|
||||
Install Homebrew for easy package management:
|
||||
```bash
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
|
||||
#### Development Tools
|
||||
```bash
|
||||
# Install Xcode Command Line Tools
|
||||
xcode-select --install
|
||||
|
||||
# Install essential development tools via Homebrew
|
||||
brew install git curl wget
|
||||
```
|
||||
|
||||
### .NET Runtime
|
||||
- .NET 6.0 runtime (automatically included with the runner)
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### 1. Download and Extract
|
||||
```bash
|
||||
# Create runner directory
|
||||
mkdir ~/actions-runner && cd ~/actions-runner
|
||||
|
||||
# Download latest release (replace with actual version)
|
||||
curl -O -L https://github.com/actions/runner/releases/download/v2.xyz.z/actions-runner-osx-x64-2.xyz.z.tar.gz
|
||||
|
||||
# Extract
|
||||
tar xzf ./actions-runner-osx-x64-2.xyz.z.tar.gz
|
||||
```
|
||||
|
||||
### 2. Configure
|
||||
```bash
|
||||
./config.sh --url https://github.com/YOUR_ORG/YOUR_REPO --token YOUR_TOKEN
|
||||
```
|
||||
|
||||
### 3. Run as Service (macOS)
|
||||
```bash
|
||||
# Install as launchd service
|
||||
sudo ./svc.sh install
|
||||
|
||||
# Start the service
|
||||
sudo ./svc.sh start
|
||||
|
||||
# Check status
|
||||
sudo ./svc.sh status
|
||||
```
|
||||
|
||||
### 4. Run Interactively (Alternative)
|
||||
```bash
|
||||
./run.sh
|
||||
```
|
||||
|
||||
## macOS-Specific Considerations
|
||||
|
||||
### Security & Privacy
|
||||
- Allow the runner executable through macOS Gatekeeper
|
||||
- Grant necessary permissions in System Preferences > Security & Privacy
|
||||
|
||||
### Code Signing
|
||||
For repositories that build macOS applications:
|
||||
```bash
|
||||
# Install certificates for code signing
|
||||
security import developer_certificates.p12 -k ~/Library/Keychains/login.keychain
|
||||
```
|
||||
|
||||
### Xcode Integration
|
||||
If building iOS/macOS apps:
|
||||
```bash
|
||||
# Install Xcode from App Store or developer portal
|
||||
# Set Xcode path
|
||||
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Permission Denied:**
|
||||
```bash
|
||||
chmod +x ./config.sh ./run.sh ./svc.sh
|
||||
```
|
||||
|
||||
**Gatekeeper Issues:**
|
||||
```bash
|
||||
# Allow unsigned binary to run
|
||||
sudo spctl --master-disable
|
||||
# Or specifically allow the runner
|
||||
sudo spctl --add ./bin/Runner.Listener
|
||||
```
|
||||
|
||||
**Service Not Starting:**
|
||||
```bash
|
||||
# Check system logs
|
||||
sudo ./svc.sh status
|
||||
tail -f ~/Library/Logs/Runner_*.log
|
||||
```
|
||||
|
||||
**Path Issues:**
|
||||
```bash
|
||||
# Ensure proper PATH in your shell profile
|
||||
echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc
|
||||
source ~/.zshrc
|
||||
```
|
||||
|
||||
### Getting Help
|
||||
|
||||
- Check our [troubleshooting guide](../checks/README.md)
|
||||
- Review [common network issues](../checks/network.md)
|
||||
- Search [GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions)
|
||||
|
||||
## [More .NET Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore30)
|
||||
|
||||
@@ -4,4 +4,92 @@
|
||||
|
||||
Please see "[Supported architectures and operating systems for self-hosted runners](https://docs.github.com/en/actions/reference/runners/self-hosted-runners#windows)."
|
||||
|
||||
## [More .NET Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore30)
|
||||
## Quick Setup
|
||||
|
||||
1. **Download** the latest runner from [releases](https://github.com/actions/runner/releases)
|
||||
2. **Extract** the downloaded archive to your desired directory
|
||||
3. **Run** `config.cmd` as Administrator to configure the runner
|
||||
4. **Install** as a service (optional): `svc.sh install` and `svc.sh start`
|
||||
|
||||
## System Requirements
|
||||
|
||||
### .NET Runtime
|
||||
- .NET 6.0 runtime (automatically installed with the runner)
|
||||
- Windows PowerShell 5.1 or PowerShell Core 6.0+
|
||||
|
||||
### Windows Features
|
||||
Windows runners require the following components:
|
||||
|
||||
```powershell
|
||||
# Enable required Windows features (run as Administrator)
|
||||
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
|
||||
```
|
||||
|
||||
### Visual Studio Build Tools (For builds requiring compilation)
|
||||
For repositories that need to compile code, install:
|
||||
|
||||
- **Visual Studio 2017 or newer** [Install here](https://visualstudio.microsoft.com)
|
||||
- **Visual Studio 2022 17.3 Preview or later** (for ARM64) [Install here](https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-notes-preview)
|
||||
|
||||
### Git for Windows
|
||||
- **Git for Windows** [Install here](https://git-scm.com/downloads) (required for repository operations)
|
||||
|
||||
## Common Setup Steps
|
||||
|
||||
### 1. Create Runner Directory
|
||||
```cmd
|
||||
mkdir C:\actions-runner
|
||||
cd C:\actions-runner
|
||||
```
|
||||
|
||||
### 2. Download and Extract
|
||||
```powershell
|
||||
# Download latest release
|
||||
Invoke-WebRequest -Uri "https://github.com/actions/runner/releases/download/v2.xyz.z/actions-runner-win-x64-2.xyz.z.zip" -OutFile "actions-runner.zip"
|
||||
# Extract
|
||||
Expand-Archive -Path "actions-runner.zip" -DestinationPath "."
|
||||
```
|
||||
|
||||
### 3. Configure
|
||||
```cmd
|
||||
.\config.cmd --url https://github.com/YOUR_ORG/YOUR_REPO --token YOUR_TOKEN
|
||||
```
|
||||
|
||||
### 4. Run as Service
|
||||
```cmd
|
||||
# Install service
|
||||
.\svc.sh install
|
||||
# Start service
|
||||
.\svc.sh start
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**PowerShell Execution Policy:**
|
||||
```powershell
|
||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||
```
|
||||
|
||||
**Windows Defender/Antivirus:**
|
||||
- Add runner directory to antivirus exclusions
|
||||
- Exclude `Runner.Listener.exe` and `Runner.Worker.exe`
|
||||
|
||||
**Firewall Issues:**
|
||||
```powershell
|
||||
# Allow runner through Windows Firewall
|
||||
New-NetFirewallRule -DisplayName "GitHub Actions Runner" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
|
||||
```
|
||||
|
||||
**Permission Issues:**
|
||||
- Run `config.cmd` as Administrator
|
||||
- Ensure the runner user has "Log on as a service" rights
|
||||
|
||||
### Getting Help
|
||||
|
||||
- Check our [troubleshooting guide](../checks/README.md)
|
||||
- Review [common issues](../checks/actions.md)
|
||||
- Search [GitHub Community Discussions](https://github.com/orgs/community/discussions/categories/actions)
|
||||
|
||||
## [More .NET Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore30)
|
||||
|
||||
@@ -5,8 +5,8 @@ ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ARG RUNNER_VERSION
|
||||
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.7.0
|
||||
ARG DOCKER_VERSION=28.5.1
|
||||
ARG BUILDX_VERSION=0.29.1
|
||||
ARG DOCKER_VERSION=28.3.2
|
||||
ARG BUILDX_VERSION=0.26.1
|
||||
|
||||
RUN apt update -y && apt install curl unzip -y
|
||||
|
||||
@@ -21,10 +21,6 @@ RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-c
|
||||
&& unzip ./runner-container-hooks.zip -d ./k8s \
|
||||
&& rm runner-container-hooks.zip
|
||||
|
||||
RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v0.8.0/actions-runner-hooks-k8s-0.8.0.zip \
|
||||
&& unzip ./runner-container-hooks.zip -d ./k8s-novolume \
|
||||
&& rm runner-container-hooks.zip
|
||||
|
||||
RUN export RUNNER_ARCH=${TARGETARCH} \
|
||||
&& if [ "$RUNNER_ARCH" = "amd64" ]; then export DOCKER_ARCH=x86_64 ; fi \
|
||||
&& if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \
|
||||
|
||||
@@ -1,43 +1,20 @@
|
||||
## What's Changed
|
||||
* Update safe_sleep.sh for bug when scheduler is paused for more than 1 second by @horner in https://github.com/actions/runner/pull/3157
|
||||
* Acknowledge runner request by @ericsciple in https://github.com/actions/runner/pull/3996
|
||||
* Update Docker to v28.3.3 and Buildx to v0.27.0 by @github-actions[bot] in https://github.com/actions/runner/pull/3999
|
||||
* Update dotnet sdk to latest version @8.0.413 by @github-actions[bot] in https://github.com/actions/runner/pull/4000
|
||||
* Bump actions/attest-build-provenance from 2 to 3 by @dependabot[bot] in https://github.com/actions/runner/pull/4002
|
||||
* Bump @typescript-eslint/eslint-plugin from 6.7.2 to 8.35.0 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3920
|
||||
* Bump husky from 8.0.3 to 9.1.7 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3842
|
||||
* Bump @vercel/ncc from 0.38.0 to 0.38.3 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3841
|
||||
* Bump eslint-plugin-github from 4.10.0 to 4.10.2 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3180
|
||||
* Bump typescript from 5.2.2 to 5.9.2 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/4007
|
||||
* chore: migrate Husky config from v8 to v9 format by @salmanmkc in https://github.com/actions/runner/pull/4003
|
||||
* Map RUNNER_TEMP for container action by @ericsciple in https://github.com/actions/runner/pull/4011
|
||||
* Break UseV2Flow into UseV2Flow and UseRunnerAdminFlow. by @TingluoHuang in https://github.com/actions/runner/pull/4013
|
||||
* Update Docker to v28.4.0 and Buildx to v0.28.0 by @github-actions[bot] in https://github.com/actions/runner/pull/4020
|
||||
* Bump node.js to latest version in runner. by @TingluoHuang in https://github.com/actions/runner/pull/4022
|
||||
* feat: add automated .NET dependency management workflow by @salmanmkc in https://github.com/actions/runner/pull/4028
|
||||
* feat: add automated Docker BuildX dependency management workflow by @salmanmkc in https://github.com/actions/runner/pull/4029
|
||||
* feat: add automated Node.js version management workflow by @salmanmkc in https://github.com/actions/runner/pull/4026
|
||||
* feat: add comprehensive NPM security management workflow by @salmanmkc in https://github.com/actions/runner/pull/4027
|
||||
* feat: add comprehensive dependency monitoring system by @salmanmkc in https://github.com/actions/runner/pull/4025
|
||||
* Use BrokerURL when using RunnerAdmin by @luketomlinson in https://github.com/actions/runner/pull/4044
|
||||
* Bump actions/github-script from 7.0.1 to 8.0.0 by @dependabot[bot] in https://github.com/actions/runner/pull/4016
|
||||
* Bump actions/stale from 9 to 10 by @dependabot[bot] in https://github.com/actions/runner/pull/4015
|
||||
* fix: prevent Node.js upgrade workflow from creating PRs with empty versions by @salmanmkc in https://github.com/actions/runner/pull/4055
|
||||
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4057
|
||||
* Bump actions/setup-node from 4 to 5 by @dependabot[bot] in https://github.com/actions/runner/pull/4037
|
||||
* Bump Azure.Storage.Blobs from 12.25.0 to 12.25.1 by @dependabot[bot] in https://github.com/actions/runner/pull/4058
|
||||
* Update Docker to v28.5.0 and Buildx to v0.29.1 by @github-actions[bot] in https://github.com/actions/runner/pull/4069
|
||||
* Bump github/codeql-action from 3 to 4 by @dependabot[bot] in https://github.com/actions/runner/pull/4072
|
||||
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4075
|
||||
* Include k8s novolume (version v0.8.0) by @nikola-jokic in https://github.com/actions/runner/pull/4063
|
||||
* Make sure runner-admin has both auth_url and auth_url_v2. by @TingluoHuang in https://github.com/actions/runner/pull/4066
|
||||
* Report job has infra failure to run-service by @TingluoHuang in https://github.com/actions/runner/pull/4073
|
||||
* Bump actions/setup-node from 5 to 6 by @dependabot[bot] in https://github.com/actions/runner/pull/4078
|
||||
* Update Docker to v28.3.2 and Buildx to v0.26.1 by @github-actions[bot] in https://github.com/actions/runner/pull/3953
|
||||
* Fix if statement structure in update script and variable reference by @salmanmkc in https://github.com/actions/runner/pull/3956
|
||||
* Add V2 flow for runner deletion by @Samirat in https://github.com/actions/runner/pull/3954
|
||||
* Node 20 -> Node 24 migration feature flagging, opt-in and opt-out environment variables by @salmanmkc in https://github.com/actions/runner/pull/3948
|
||||
* Update Node20 and Node24 to latest by @djs-intel in https://github.com/actions/runner/pull/3972
|
||||
* Redirect supported OS doc section to current public Docs location by @corycalahan in https://github.com/actions/runner/pull/3979
|
||||
* Bump Microsoft.NET.Test.Sdk from 17.13.0 to 17.14.1 by @dependabot[bot] in https://github.com/actions/runner/pull/3975
|
||||
* Bump Azure.Storage.Blobs from 12.24.0 to 12.25.0 by @dependabot[bot] in https://github.com/actions/runner/pull/3974
|
||||
* Bump actions/download-artifact from 4 to 5 by @dependabot[bot] in https://github.com/actions/runner/pull/3973
|
||||
* Bump actions/checkout from 4 to 5 by @dependabot[bot] in https://github.com/actions/runner/pull/3982
|
||||
|
||||
## New Contributors
|
||||
* @horner made their first contribution in https://github.com/actions/runner/pull/3157
|
||||
* @Samirat made their first contribution in https://github.com/actions/runner/pull/3954
|
||||
* @djs-intel made their first contribution in https://github.com/actions/runner/pull/3972
|
||||
|
||||
**Full Changelog**: https://github.com/actions/runner/compare/v2.328.0...v2.329.0
|
||||
**Full Changelog**: https://github.com/actions/runner/compare/v2.327.1...v2.328.0
|
||||
|
||||
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
|
||||
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
|
||||
|
||||
1085
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
1085
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@
|
||||
"lint": "eslint src/**/*.ts",
|
||||
"pack": "ncc build -o ../../layoutbin/hashFiles",
|
||||
"all": "npm run format && npm run lint && npm run build && npm run pack",
|
||||
"prepare": "cd ../../../../ && husky"
|
||||
"prepare": "cd ../../../../ && husky install"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -36,15 +36,15 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.6.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
||||
"@typescript-eslint/parser": "^6.7.2",
|
||||
"@vercel/ncc": "^0.38.3",
|
||||
"@vercel/ncc": "^0.38.0",
|
||||
"eslint": "^8.47.0",
|
||||
"eslint-plugin-github": "^4.10.2",
|
||||
"eslint-plugin-github": "^4.10.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"husky": "^9.1.7",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^15.5.0",
|
||||
"prettier": "^3.0.3",
|
||||
"typescript": "^5.9.2"
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ NODE_URL=https://nodejs.org/dist
|
||||
NODE_ALPINE_URL=https://github.com/actions/alpine_nodejs/releases/download
|
||||
# When you update Node versions you must also create a new release of alpine_nodejs at that updated version.
|
||||
# Follow the instructions here: https://github.com/actions/alpine_nodejs?tab=readme-ov-file#getting-started
|
||||
NODE20_VERSION="20.19.5"
|
||||
NODE24_VERSION="24.10.0"
|
||||
NODE20_VERSION="20.19.4"
|
||||
NODE24_VERSION="24.5.0"
|
||||
|
||||
get_abs_path() {
|
||||
# exploits the fact that pwd will print abs path when no args
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
SECONDS=0
|
||||
while [[ $SECONDS -lt $1 ]]; do
|
||||
while [[ $SECONDS != $1 ]]; do
|
||||
:
|
||||
done
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace GitHub.Runner.Common
|
||||
|
||||
Task<TaskAgentMessage> GetRunnerMessageAsync(Guid? sessionId, TaskAgentStatus status, string version, string os, string architecture, bool disableUpdate, CancellationToken token);
|
||||
|
||||
Task AcknowledgeRunnerRequestAsync(string runnerRequestId, Guid? sessionId, TaskAgentStatus status, string version, string os, string architecture, CancellationToken token);
|
||||
|
||||
Task UpdateConnectionIfNeeded(Uri serverUri, VssCredentials credentials);
|
||||
|
||||
Task ForceRefreshConnection(VssCredentials credentials);
|
||||
@@ -69,17 +67,10 @@ namespace GitHub.Runner.Common
|
||||
var brokerSession = RetryRequest<TaskAgentMessage>(
|
||||
async () => await _brokerHttpClient.GetRunnerMessageAsync(sessionId, version, status, os, architecture, disableUpdate, cancellationToken), cancellationToken, shouldRetry: ShouldRetryException);
|
||||
|
||||
|
||||
return brokerSession;
|
||||
}
|
||||
|
||||
public async Task AcknowledgeRunnerRequestAsync(string runnerRequestId, Guid? sessionId, TaskAgentStatus status, string version, string os, string architecture, CancellationToken cancellationToken)
|
||||
{
|
||||
CheckConnection();
|
||||
|
||||
// No retries
|
||||
await _brokerHttpClient.AcknowledgeRunnerRequestAsync(runnerRequestId, sessionId, version, status, os, architecture, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task DeleteSessionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
CheckConnection();
|
||||
|
||||
@@ -53,9 +53,6 @@ namespace GitHub.Runner.Common
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public bool UseV2Flow { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public bool UseRunnerAdminFlow { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public string ServerUrlV2 { get; set; }
|
||||
|
||||
|
||||
@@ -169,9 +169,6 @@ namespace GitHub.Runner.Common
|
||||
public static readonly string AllowRunnerContainerHooks = "DistributedTask.AllowRunnerContainerHooks";
|
||||
public static readonly string AddCheckRunIdToJobContext = "actions_add_check_run_id_to_job_context";
|
||||
public static readonly string DisplayHelpfulActionsDownloadErrors = "actions_display_helpful_actions_download_errors";
|
||||
public static readonly string ContainerActionRunnerTemp = "actions_container_action_runner_temp";
|
||||
public static readonly string SnapshotPreflightHostedRunnerCheck = "actions_snapshot_preflight_hosted_runner_check";
|
||||
public static readonly string SnapshotPreflightImageGenPoolCheck = "actions_snapshot_preflight_image_gen_pool_check";
|
||||
}
|
||||
|
||||
// Node version migration related constants
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace GitHub.Runner.Common
|
||||
string environmentUrl,
|
||||
IList<Telemetry> telemetry,
|
||||
string billingOwnerId,
|
||||
string infrastructureFailureCategory,
|
||||
CancellationToken token);
|
||||
|
||||
Task<RenewJobResponse> RenewJobAsync(Guid planId, Guid jobId, CancellationToken token);
|
||||
@@ -81,12 +80,11 @@ namespace GitHub.Runner.Common
|
||||
string environmentUrl,
|
||||
IList<Telemetry> telemetry,
|
||||
string billingOwnerId,
|
||||
string infrastructureFailureCategory,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
CheckConnection();
|
||||
return RetryRequest(
|
||||
async () => await _runServiceHttpClient.CompleteJobAsync(requestUri, planId, jobId, result, outputs, stepResults, jobAnnotations, environmentUrl, telemetry, billingOwnerId, infrastructureFailureCategory, cancellationToken), cancellationToken,
|
||||
async () => await _runServiceHttpClient.CompleteJobAsync(requestUri, planId, jobId, result, outputs, stepResults, jobAnnotations, environmentUrl, telemetry, billingOwnerId, cancellationToken), cancellationToken,
|
||||
shouldRetry: ex =>
|
||||
ex is not VssUnauthorizedException && // HTTP status 401
|
||||
ex is not TaskOrchestrationJobNotFoundException); // HTTP status 404
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace GitHub.Runner.Common
|
||||
|
||||
protected async Task RetryRequest(Func<Task> func,
|
||||
CancellationToken cancellationToken,
|
||||
int maxAttempts = 5,
|
||||
int maxRetryAttemptsCount = 5,
|
||||
Func<Exception, bool> shouldRetry = null
|
||||
)
|
||||
{
|
||||
@@ -79,31 +79,31 @@ namespace GitHub.Runner.Common
|
||||
await func();
|
||||
return Unit.Value;
|
||||
}
|
||||
await RetryRequest<Unit>(wrappedFunc, cancellationToken, maxAttempts, shouldRetry);
|
||||
await RetryRequest<Unit>(wrappedFunc, cancellationToken, maxRetryAttemptsCount, shouldRetry);
|
||||
}
|
||||
|
||||
protected async Task<T> RetryRequest<T>(Func<Task<T>> func,
|
||||
CancellationToken cancellationToken,
|
||||
int maxAttempts = 5,
|
||||
int maxRetryAttemptsCount = 5,
|
||||
Func<Exception, bool> shouldRetry = null
|
||||
)
|
||||
{
|
||||
var attempt = 0;
|
||||
var retryCount = 0;
|
||||
while (true)
|
||||
{
|
||||
attempt++;
|
||||
retryCount++;
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
try
|
||||
{
|
||||
return await func();
|
||||
}
|
||||
// TODO: Add handling of non-retriable exceptions: https://github.com/github/actions-broker/issues/122
|
||||
catch (Exception ex) when (attempt < maxAttempts && (shouldRetry == null || shouldRetry(ex)))
|
||||
catch (Exception ex) when (retryCount < maxRetryAttemptsCount && (shouldRetry == null || shouldRetry(ex)))
|
||||
{
|
||||
Trace.Error("Catch exception during request");
|
||||
Trace.Error(ex);
|
||||
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
||||
Trace.Warning($"Back off {backOff.TotalSeconds} seconds before next retry. {maxAttempts - attempt} attempt left.");
|
||||
Trace.Warning($"Back off {backOff.TotalSeconds} seconds before next retry. {maxRetryAttemptsCount - retryCount} attempt left.");
|
||||
await Task.Delay(backOff, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace GitHub.Runner.Listener
|
||||
private RunnerSettings _settings;
|
||||
private ITerminal _term;
|
||||
private TimeSpan _getNextMessageRetryInterval;
|
||||
private TaskAgentStatus _runnerStatus = TaskAgentStatus.Online;
|
||||
private TaskAgentStatus runnerStatus = TaskAgentStatus.Online;
|
||||
private CancellationTokenSource _getMessagesTokenSource;
|
||||
private VssCredentials _creds;
|
||||
private VssCredentials _credsV2;
|
||||
@@ -258,7 +258,7 @@ namespace GitHub.Runner.Listener
|
||||
public void OnJobStatus(object sender, JobStatusEventArgs e)
|
||||
{
|
||||
Trace.Info("Received job status event. JobState: {0}", e.Status);
|
||||
_runnerStatus = e.Status;
|
||||
runnerStatus = e.Status;
|
||||
try
|
||||
{
|
||||
_getMessagesTokenSource?.Cancel();
|
||||
@@ -291,7 +291,7 @@ namespace GitHub.Runner.Listener
|
||||
}
|
||||
|
||||
message = await _brokerServer.GetRunnerMessageAsync(_session.SessionId,
|
||||
_runnerStatus,
|
||||
runnerStatus,
|
||||
BuildConstants.RunnerPackage.Version,
|
||||
VarUtil.OS,
|
||||
VarUtil.OSArchitecture,
|
||||
@@ -417,21 +417,6 @@ namespace GitHub.Runner.Listener
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task AcknowledgeMessageAsync(string runnerRequestId, CancellationToken cancellationToken)
|
||||
{
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); // Short timeout
|
||||
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
Trace.Info($"Acknowledging runner request '{runnerRequestId}'.");
|
||||
await _brokerServer.AcknowledgeRunnerRequestAsync(
|
||||
runnerRequestId,
|
||||
_session.SessionId,
|
||||
_runnerStatus,
|
||||
BuildConstants.RunnerPackage.Version,
|
||||
VarUtil.OS,
|
||||
VarUtil.OSArchitecture,
|
||||
linkedCts.Token);
|
||||
}
|
||||
|
||||
private bool IsGetNextMessageExceptionRetriable(Exception ex)
|
||||
{
|
||||
if (ex is TaskAgentNotFoundException ||
|
||||
|
||||
@@ -153,8 +153,8 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
registerToken = await GetRunnerTokenAsync(command, inputUrl, "registration");
|
||||
GitHubAuthResult authResult = await GetTenantCredential(inputUrl, registerToken, Constants.RunnerEvent.Register);
|
||||
runnerSettings.ServerUrl = authResult.TenantUrl;
|
||||
runnerSettings.UseRunnerAdminFlow = authResult.UseRunnerAdminFlow;
|
||||
Trace.Info($"Using runner-admin flow: {runnerSettings.UseRunnerAdminFlow}");
|
||||
runnerSettings.UseV2Flow = authResult.UseV2Flow;
|
||||
Trace.Info($"Using V2 flow: {runnerSettings.UseV2Flow}");
|
||||
creds = authResult.ToVssCredentials();
|
||||
Trace.Info("cred retrieved via GitHub auth");
|
||||
}
|
||||
@@ -211,7 +211,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
string poolName = null;
|
||||
TaskAgentPool agentPool = null;
|
||||
List<TaskAgentPool> agentPools;
|
||||
if (runnerSettings.UseRunnerAdminFlow)
|
||||
if (runnerSettings.UseV2Flow)
|
||||
{
|
||||
agentPools = await _dotcomServer.GetRunnerGroupsAsync(runnerSettings.GitHubUrl, registerToken);
|
||||
}
|
||||
@@ -259,7 +259,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
var userLabels = command.GetLabels();
|
||||
_term.WriteLine();
|
||||
List<TaskAgent> agents;
|
||||
if (runnerSettings.UseRunnerAdminFlow)
|
||||
if (runnerSettings.UseV2Flow)
|
||||
{
|
||||
agents = await _dotcomServer.GetRunnerByNameAsync(runnerSettings.GitHubUrl, registerToken, runnerSettings.AgentName);
|
||||
}
|
||||
@@ -280,11 +280,10 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
|
||||
try
|
||||
{
|
||||
if (runnerSettings.UseRunnerAdminFlow)
|
||||
if (runnerSettings.UseV2Flow)
|
||||
{
|
||||
var runner = await _dotcomServer.ReplaceRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML);
|
||||
runnerSettings.ServerUrlV2 = runner.RunnerAuthorization.ServerUrl;
|
||||
runnerSettings.UseV2Flow = true; // if we are using runner admin, we also need to hit broker
|
||||
|
||||
agent.Id = runner.Id;
|
||||
agent.Authorization = new TaskAgentAuthorization()
|
||||
@@ -292,13 +291,6 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
AuthorizationUrl = runner.RunnerAuthorization.AuthorizationUrl,
|
||||
ClientId = new Guid(runner.RunnerAuthorization.ClientId)
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(runner.RunnerAuthorization.LegacyAuthorizationUrl?.AbsoluteUri))
|
||||
{
|
||||
agent.Authorization.AuthorizationUrl = runner.RunnerAuthorization.LegacyAuthorizationUrl;
|
||||
agent.Properties["EnableAuthMigrationByDefault"] = true;
|
||||
agent.Properties["AuthorizationUrlV2"] = runner.RunnerAuthorization.AuthorizationUrl.AbsoluteUri;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -338,11 +330,10 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
|
||||
try
|
||||
{
|
||||
if (runnerSettings.UseRunnerAdminFlow)
|
||||
if (runnerSettings.UseV2Flow)
|
||||
{
|
||||
var runner = await _dotcomServer.AddRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML);
|
||||
runnerSettings.ServerUrlV2 = runner.RunnerAuthorization.ServerUrl;
|
||||
runnerSettings.UseV2Flow = true; // if we are using runner admin, we also need to hit broker
|
||||
|
||||
agent.Id = runner.Id;
|
||||
agent.Authorization = new TaskAgentAuthorization()
|
||||
@@ -350,13 +341,6 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
AuthorizationUrl = runner.RunnerAuthorization.AuthorizationUrl,
|
||||
ClientId = new Guid(runner.RunnerAuthorization.ClientId)
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(runner.RunnerAuthorization.LegacyAuthorizationUrl?.AbsoluteUri))
|
||||
{
|
||||
agent.Authorization.AuthorizationUrl = runner.RunnerAuthorization.LegacyAuthorizationUrl;
|
||||
agent.Properties["EnableAuthMigrationByDefault"] = true;
|
||||
agent.Properties["AuthorizationUrlV2"] = runner.RunnerAuthorization.AuthorizationUrl.AbsoluteUri;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -416,26 +400,13 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
throw new NotSupportedException("Message queue listen OAuth token.");
|
||||
}
|
||||
|
||||
// allow the server to override the serverUrlV2 and useV2Flow
|
||||
if (agent.Properties.TryGetValue("ServerUrlV2", out string serverUrlV2) &&
|
||||
!string.IsNullOrEmpty(serverUrlV2))
|
||||
{
|
||||
Trace.Info($"Service enforced serverUrlV2: {serverUrlV2}");
|
||||
runnerSettings.ServerUrlV2 = serverUrlV2;
|
||||
}
|
||||
|
||||
if (agent.Properties.TryGetValue("UseV2Flow", out bool useV2Flow) && useV2Flow)
|
||||
{
|
||||
Trace.Info($"Service enforced useV2Flow: {useV2Flow}");
|
||||
runnerSettings.UseV2Flow = useV2Flow;
|
||||
}
|
||||
|
||||
// Testing agent connection, detect any potential connection issue, like local clock skew that cause OAuth token expired.
|
||||
|
||||
if (!runnerSettings.UseV2Flow && !runnerSettings.UseRunnerAdminFlow)
|
||||
if (!runnerSettings.UseV2Flow)
|
||||
{
|
||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
||||
VssCredentials credential = credMgr.LoadCredentials(allowAuthUrlV2: false);
|
||||
@@ -458,6 +429,20 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
// allow the server to override the serverUrlV2 and useV2Flow
|
||||
if (agent.Properties.TryGetValue("ServerUrlV2", out string serverUrlV2) &&
|
||||
!string.IsNullOrEmpty(serverUrlV2))
|
||||
{
|
||||
Trace.Info($"Service enforced serverUrlV2: {serverUrlV2}");
|
||||
runnerSettings.ServerUrlV2 = serverUrlV2;
|
||||
}
|
||||
|
||||
if (agent.Properties.TryGetValue("UseV2Flow", out bool useV2Flow) && useV2Flow)
|
||||
{
|
||||
Trace.Info($"Service enforced useV2Flow: {useV2Flow}");
|
||||
runnerSettings.UseV2Flow = useV2Flow;
|
||||
}
|
||||
|
||||
_term.WriteSection("Runner settings");
|
||||
|
||||
// We will Combine() what's stored with root. Defaults to string a relative path
|
||||
@@ -553,7 +538,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
{
|
||||
RunnerSettings settings = _store.GetSettings();
|
||||
|
||||
if (settings.UseRunnerAdminFlow)
|
||||
if (settings.UseV2Flow)
|
||||
{
|
||||
var deletionToken = await GetRunnerTokenAsync(command, settings.GitHubUrl, "remove");
|
||||
await _dotcomServer.DeleteRunnerAsync(settings.GitHubUrl, deletionToken, settings.AgentId);
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
public string Token { get; set; }
|
||||
|
||||
[DataMember(Name = "use_v2_flow")]
|
||||
public bool UseRunnerAdminFlow { get; set; }
|
||||
public bool UseV2Flow { get; set; }
|
||||
|
||||
public VssCredentials ToVssCredentials()
|
||||
{
|
||||
|
||||
@@ -1211,7 +1211,7 @@ namespace GitHub.Runner.Listener
|
||||
jobAnnotations.Add(annotation.Value);
|
||||
}
|
||||
|
||||
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, TaskResult.Failed, outputs: null, stepResults: null, jobAnnotations: jobAnnotations, environmentUrl: null, telemetry: null, billingOwnerId: message.BillingOwnerId, infrastructureFailureCategory: null, CancellationToken.None);
|
||||
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, TaskResult.Failed, outputs: null, stepResults: null, jobAnnotations: jobAnnotations, environmentUrl: null, telemetry: null, billingOwnerId: message.BillingOwnerId, CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,6 @@ namespace GitHub.Runner.Listener
|
||||
Task DeleteSessionAsync();
|
||||
Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token);
|
||||
Task DeleteMessageAsync(TaskAgentMessage message);
|
||||
Task AcknowledgeMessageAsync(string runnerRequestId, CancellationToken cancellationToken);
|
||||
|
||||
Task RefreshListenerTokenAsync();
|
||||
void OnJobStatus(object sender, JobStatusEventArgs e);
|
||||
@@ -53,7 +52,7 @@ namespace GitHub.Runner.Listener
|
||||
private readonly TimeSpan _sessionConflictRetryLimit = TimeSpan.FromMinutes(4);
|
||||
private readonly TimeSpan _clockSkewRetryLimit = TimeSpan.FromMinutes(30);
|
||||
private readonly Dictionary<string, int> _sessionCreationExceptionTracker = new();
|
||||
private TaskAgentStatus _runnerStatus = TaskAgentStatus.Online;
|
||||
private TaskAgentStatus runnerStatus = TaskAgentStatus.Online;
|
||||
private CancellationTokenSource _getMessagesTokenSource;
|
||||
private VssCredentials _creds;
|
||||
private VssCredentials _credsV2;
|
||||
@@ -218,7 +217,7 @@ namespace GitHub.Runner.Listener
|
||||
public void OnJobStatus(object sender, JobStatusEventArgs e)
|
||||
{
|
||||
Trace.Info("Received job status event. JobState: {0}", e.Status);
|
||||
_runnerStatus = e.Status;
|
||||
runnerStatus = e.Status;
|
||||
try
|
||||
{
|
||||
_getMessagesTokenSource?.Cancel();
|
||||
@@ -251,7 +250,7 @@ namespace GitHub.Runner.Listener
|
||||
message = await _runnerServer.GetAgentMessageAsync(_settings.PoolId,
|
||||
_session.SessionId,
|
||||
_lastMessageId,
|
||||
_runnerStatus,
|
||||
runnerStatus,
|
||||
BuildConstants.RunnerPackage.Version,
|
||||
VarUtil.OS,
|
||||
VarUtil.OSArchitecture,
|
||||
@@ -275,7 +274,7 @@ namespace GitHub.Runner.Listener
|
||||
}
|
||||
|
||||
message = await _brokerServer.GetRunnerMessageAsync(_session.SessionId,
|
||||
_runnerStatus,
|
||||
runnerStatus,
|
||||
BuildConstants.RunnerPackage.Version,
|
||||
VarUtil.OS,
|
||||
VarUtil.OSArchitecture,
|
||||
@@ -438,21 +437,6 @@ namespace GitHub.Runner.Listener
|
||||
await _brokerServer.ForceRefreshConnection(_credsV2);
|
||||
}
|
||||
|
||||
public async Task AcknowledgeMessageAsync(string runnerRequestId, CancellationToken cancellationToken)
|
||||
{
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); // Short timeout
|
||||
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
Trace.Info($"Acknowledging runner request '{runnerRequestId}'.");
|
||||
await _brokerServer.AcknowledgeRunnerRequestAsync(
|
||||
runnerRequestId,
|
||||
_session.SessionId,
|
||||
_runnerStatus,
|
||||
BuildConstants.RunnerPackage.Version,
|
||||
VarUtil.OS,
|
||||
VarUtil.OSArchitecture,
|
||||
linkedCts.Token);
|
||||
}
|
||||
|
||||
private TaskAgentMessage DecryptMessage(TaskAgentMessage message)
|
||||
{
|
||||
if (_session.EncryptionKey == null ||
|
||||
|
||||
@@ -654,42 +654,22 @@ namespace GitHub.Runner.Listener
|
||||
else
|
||||
{
|
||||
var messageRef = StringUtil.ConvertFromJson<RunnerJobRequestRef>(message.Body);
|
||||
|
||||
// Acknowledge (best-effort)
|
||||
if (messageRef.ShouldAcknowledge) // Temporary feature flag
|
||||
{
|
||||
try
|
||||
{
|
||||
await _listener.AcknowledgeMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.Error($"Best-effort acknowledge failed for request '{messageRef.RunnerRequestId}'");
|
||||
Trace.Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Pipelines.AgentJobRequestMessage jobRequestMessage = null;
|
||||
|
||||
// Create connection
|
||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
||||
if (string.IsNullOrEmpty(messageRef.RunServiceUrl))
|
||||
{
|
||||
// Connect
|
||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
||||
var creds = credMgr.LoadCredentials(allowAuthUrlV2: false);
|
||||
var actionsRunServer = HostContext.CreateService<IActionsRunServer>();
|
||||
await actionsRunServer.ConnectAsync(new Uri(settings.ServerUrl), creds);
|
||||
|
||||
// Get job message
|
||||
jobRequestMessage = await actionsRunServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Connect
|
||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
||||
var credsV2 = credMgr.LoadCredentials(allowAuthUrlV2: true);
|
||||
var runServer = HostContext.CreateService<IRunServer>();
|
||||
await runServer.ConnectAsync(new Uri(messageRef.RunServiceUrl), credsV2);
|
||||
|
||||
// Get job message
|
||||
try
|
||||
{
|
||||
jobRequestMessage = await runServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageRef.BillingOwnerId, messageQueueLoopTokenSource.Token);
|
||||
@@ -718,10 +698,7 @@ namespace GitHub.Runner.Listener
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch
|
||||
jobDispatcher.Run(jobRequestMessage, runOnce);
|
||||
|
||||
// Run once?
|
||||
if (runOnce)
|
||||
{
|
||||
Trace.Info("One time used runner received job message.");
|
||||
|
||||
@@ -10,9 +10,6 @@ namespace GitHub.Runner.Listener
|
||||
|
||||
[DataMember(Name = "runner_request_id")]
|
||||
public string RunnerRequestId { get; set; }
|
||||
|
||||
[DataMember(Name = "should_acknowledge")]
|
||||
public bool ShouldAcknowledge { get; set; }
|
||||
|
||||
[DataMember(Name = "run_service_url")]
|
||||
public string RunServiceUrl { get; set; }
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
// Log the error and fail the PrepareActionsAsync Initialization.
|
||||
Trace.Error($"Caught exception from PrepareActionsAsync Initialization: {ex}");
|
||||
executionContext.InfrastructureError(ex.Message, category: "resolve_action");
|
||||
executionContext.InfrastructureError(ex.Message);
|
||||
executionContext.Result = TaskResult.Failed;
|
||||
throw;
|
||||
}
|
||||
@@ -119,7 +119,7 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
// Log the error and fail the PrepareActionsAsync Initialization.
|
||||
Trace.Error($"Caught exception from PrepareActionsAsync Initialization: {ex}");
|
||||
executionContext.InfrastructureError(ex.Message, category: "invalid_action_download");
|
||||
executionContext.InfrastructureError(ex.Message);
|
||||
executionContext.Result = TaskResult.Failed;
|
||||
throw;
|
||||
}
|
||||
@@ -777,15 +777,15 @@ namespace GitHub.Runner.Worker
|
||||
IOUtil.DeleteDirectory(destDirectory, executionContext.CancellationToken);
|
||||
Directory.CreateDirectory(destDirectory);
|
||||
|
||||
if (downloadInfo.PackageDetails != null)
|
||||
if (downloadInfo.PackageDetails != null)
|
||||
{
|
||||
executionContext.Output($"##[group]Download immutable action package '{downloadInfo.NameWithOwner}@{downloadInfo.Ref}'");
|
||||
executionContext.Output($"Version: {downloadInfo.PackageDetails.Version}");
|
||||
executionContext.Output($"Digest: {downloadInfo.PackageDetails.ManifestDigest}");
|
||||
executionContext.Output($"Source commit SHA: {downloadInfo.ResolvedSha}");
|
||||
executionContext.Output("##[endgroup]");
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
executionContext.Output($"Download action repository '{downloadInfo.NameWithOwner}@{downloadInfo.Ref}' (SHA:{downloadInfo.ResolvedSha})");
|
||||
}
|
||||
|
||||
@@ -522,10 +522,6 @@ namespace GitHub.Runner.Worker
|
||||
if (annotation != null)
|
||||
{
|
||||
stepResult.Annotations.Add(annotation.Value);
|
||||
if (annotation.Value.IsInfrastructureIssue && string.IsNullOrEmpty(Global.InfrastructureFailureCategory))
|
||||
{
|
||||
Global.InfrastructureFailureCategory = issue.Category;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1339,9 +1335,9 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
|
||||
// Do not add a format string overload. See comment on ExecutionContext.Write().
|
||||
public static void InfrastructureError(this IExecutionContext context, string message, string category = null)
|
||||
public static void InfrastructureError(this IExecutionContext context, string message)
|
||||
{
|
||||
var issue = new Issue() { Type = IssueType.Error, Message = message, IsInfrastructureIssue = true, Category = category };
|
||||
var issue = new Issue() { Type = IssueType.Error, Message = message, IsInfrastructureIssue = true };
|
||||
context.AddIssue(issue, ExecutionContextLogOptions.Default);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,5 @@ namespace GitHub.Runner.Worker
|
||||
var isContainerHooksPathSet = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(Constants.Hooks.ContainerHooksPath));
|
||||
return isContainerHookFeatureFlagSet && isContainerHooksPathSet;
|
||||
}
|
||||
|
||||
public static bool IsContainerActionRunnerTempEnabled(Variables variables)
|
||||
{
|
||||
return variables?.GetBoolean(Constants.Runner.Features.ContainerActionRunnerTemp) ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ namespace GitHub.Runner.Worker
|
||||
public StepsContext StepsContext { get; set; }
|
||||
public Variables Variables { get; set; }
|
||||
public bool WriteDebug { get; set; }
|
||||
public string InfrastructureFailureCategory { get; set; }
|
||||
public JObject ContainerHookState { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,19 +191,11 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
ArgUtil.Directory(tempWorkflowDirectory, nameof(tempWorkflowDirectory));
|
||||
|
||||
container.MountVolumes.Add(new MountVolume("/var/run/docker.sock", "/var/run/docker.sock"));
|
||||
if (FeatureManager.IsContainerActionRunnerTempEnabled(ExecutionContext.Global.Variables))
|
||||
{
|
||||
container.MountVolumes.Add(new MountVolume(tempDirectory, "/github/runner_temp"));
|
||||
}
|
||||
container.MountVolumes.Add(new MountVolume(tempHomeDirectory, "/github/home"));
|
||||
container.MountVolumes.Add(new MountVolume(tempWorkflowDirectory, "/github/workflow"));
|
||||
container.MountVolumes.Add(new MountVolume(tempFileCommandDirectory, "/github/file_commands"));
|
||||
container.MountVolumes.Add(new MountVolume(defaultWorkingDirectory, "/github/workspace"));
|
||||
|
||||
if (FeatureManager.IsContainerActionRunnerTempEnabled(ExecutionContext.Global.Variables))
|
||||
{
|
||||
container.AddPathTranslateMapping(tempDirectory, "/github/runner_temp");
|
||||
}
|
||||
container.AddPathTranslateMapping(tempHomeDirectory, "/github/home");
|
||||
container.AddPathTranslateMapping(tempWorkflowDirectory, "/github/workflow");
|
||||
container.AddPathTranslateMapping(tempFileCommandDirectory, "/github/file_commands");
|
||||
|
||||
@@ -400,10 +400,6 @@ namespace GitHub.Runner.Worker
|
||||
if (snapshotRequest != null)
|
||||
{
|
||||
var snapshotOperationProvider = HostContext.GetService<ISnapshotOperationProvider>();
|
||||
// Check that that runner is capable of taking a snapshot
|
||||
snapshotOperationProvider.RunSnapshotPreflightChecks(context);
|
||||
|
||||
// Add postjob step to write snapshot file
|
||||
jobContext.RegisterPostJobStep(new JobExtensionRunner(
|
||||
runAsync: (executionContext, _) => snapshotOperationProvider.CreateSnapshotRequestAsync(executionContext, snapshotRequest),
|
||||
condition: snapshotRequest.Condition,
|
||||
|
||||
@@ -321,7 +321,7 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
try
|
||||
{
|
||||
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, result, jobContext.JobOutputs, jobContext.Global.StepsResult, jobContext.Global.JobAnnotations, environmentUrl, telemetry, billingOwnerId: message.BillingOwnerId, infrastructureFailureCategory: jobContext.Global.InfrastructureFailureCategory, default);
|
||||
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, result, jobContext.JobOutputs, jobContext.Global.StepsResult, jobContext.Global.JobAnnotations, environmentUrl, telemetry, billingOwnerId: message.BillingOwnerId, default);
|
||||
return result;
|
||||
}
|
||||
catch (VssUnauthorizedException ex)
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.Runner.Worker.Handlers;
|
||||
namespace GitHub.Runner.Worker;
|
||||
|
||||
[ServiceLocator(Default = typeof(SnapshotOperationProvider))]
|
||||
public interface ISnapshotOperationProvider : IRunnerService
|
||||
{
|
||||
Task CreateSnapshotRequestAsync(IExecutionContext executionContext, Snapshot snapshotRequest);
|
||||
void RunSnapshotPreflightChecks(IExecutionContext jobContext);
|
||||
}
|
||||
|
||||
public class SnapshotOperationProvider : RunnerService, ISnapshotOperationProvider
|
||||
@@ -28,32 +24,9 @@ public class SnapshotOperationProvider : RunnerService, ISnapshotOperationProvid
|
||||
}
|
||||
|
||||
IOUtil.SaveObject(snapshotRequest, snapshotRequestFilePath);
|
||||
executionContext.Output($"Image Name: {snapshotRequest.ImageName} Version: {snapshotRequest.Version}");
|
||||
executionContext.Output($"Request written to: {snapshotRequestFilePath}");
|
||||
executionContext.Output("This request will be processed after the job completes. You will not receive any feedback on the snapshot process within the workflow logs of this job.");
|
||||
executionContext.Output("If the snapshot process is successful, you should see a new image with the requested name in the list of available custom images when creating a new GitHub-hosted Runner.");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void RunSnapshotPreflightChecks(IExecutionContext context)
|
||||
{
|
||||
var shouldCheckRunnerEnvironment = context.Global.Variables.GetBoolean(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck) ?? false;
|
||||
if (shouldCheckRunnerEnvironment &&
|
||||
context.Global.Variables.TryGetValue(WellKnownDistributedTaskVariables.RunnerEnvironment, out var runnerEnvironment) &&
|
||||
!string.IsNullOrEmpty(runnerEnvironment))
|
||||
{
|
||||
context.Debug($"Snapshot: RUNNER_ENVIRONMENT={runnerEnvironment}");
|
||||
if (!string.Equals(runnerEnvironment, "github-hosted", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("Snapshot workflows must be run on a GitHub Hosted Runner");
|
||||
}
|
||||
}
|
||||
var imageGenEnabled = StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED"));
|
||||
context.Debug($"Snapshot: GITHUB_ACTIONS_IMAGE_GEN_ENABLED={imageGenEnabled}");
|
||||
var shouldCheckImageGenPool = context.Global.Variables.GetBoolean(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck) ?? false;
|
||||
if (shouldCheckImageGenPool && !imageGenEnabled)
|
||||
{
|
||||
throw new ArgumentException("Snapshot workflows must be run a hosted runner with Image Generation enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,16 +18,6 @@ namespace GitHub.DistributedTask.WebApi
|
||||
internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The url to refresh tokens with legacy service
|
||||
/// </summary>
|
||||
[JsonProperty("legacy_authorization_url")]
|
||||
public Uri LegacyAuthorizationUrl
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The url to connect to poll for messages
|
||||
/// </summary>
|
||||
|
||||
@@ -35,8 +35,5 @@ namespace GitHub.Actions.RunService.WebApi
|
||||
|
||||
[DataMember(Name = "billingOwnerId", EmitDefaultValue = false)]
|
||||
public string BillingOwnerId { get; set; }
|
||||
|
||||
[DataMember(Name = "infrastructureFailureCategory", EmitDefaultValue = false)]
|
||||
public string InfrastructureFailureCategory { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace Sdk.RSWebApi.Contracts
|
||||
StartColumn = columnNumber,
|
||||
EndColumn = endColumnNumber,
|
||||
StepNumber = stepNumber,
|
||||
IsInfrastructureIssue = issue.IsInfrastructureIssue ?? false
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,6 @@ namespace GitHub.Actions.RunService.WebApi
|
||||
string environmentUrl,
|
||||
IList<Telemetry> telemetry,
|
||||
string billingOwnerId,
|
||||
string infrastructureFailureCategory,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
HttpMethod httpMethod = new HttpMethod("POST");
|
||||
@@ -146,7 +145,6 @@ namespace GitHub.Actions.RunService.WebApi
|
||||
EnvironmentUrl = environmentUrl,
|
||||
Telemetry = telemetry,
|
||||
BillingOwnerId = billingOwnerId,
|
||||
InfrastructureFailureCategory = infrastructureFailureCategory
|
||||
};
|
||||
|
||||
requestUri = new Uri(requestUri, "completejob");
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Storage.Blobs" Version="12.25.1" />
|
||||
<PackageReference Include="Azure.Storage.Blobs" Version="12.25.0" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
|
||||
|
||||
@@ -79,7 +79,6 @@ namespace GitHub.Actions.RunService.WebApi
|
||||
{
|
||||
queryParams.Add("status", status.Value.ToString());
|
||||
}
|
||||
|
||||
if (runnerVersion != null)
|
||||
{
|
||||
queryParams.Add("runnerVersion", runnerVersion);
|
||||
@@ -143,6 +142,7 @@ namespace GitHub.Actions.RunService.WebApi
|
||||
}
|
||||
|
||||
public async Task<TaskAgentSession> CreateSessionAsync(
|
||||
|
||||
TaskAgentSession session,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -191,76 +191,6 @@ namespace GitHub.Actions.RunService.WebApi
|
||||
throw new Exception($"Failed to delete broker session: {result.Error}");
|
||||
}
|
||||
|
||||
public async Task AcknowledgeRunnerRequestAsync(
|
||||
string runnerRequestId,
|
||||
Guid? sessionId,
|
||||
string runnerVersion,
|
||||
TaskAgentStatus? status,
|
||||
string os = null,
|
||||
string architecture = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
// URL
|
||||
var requestUri = new Uri(Client.BaseAddress, "acknowledge");
|
||||
|
||||
// Query parameters
|
||||
List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>();
|
||||
if (sessionId != null)
|
||||
{
|
||||
queryParams.Add("sessionId", sessionId.Value.ToString());
|
||||
}
|
||||
if (status != null)
|
||||
{
|
||||
queryParams.Add("status", status.Value.ToString());
|
||||
}
|
||||
if (runnerVersion != null)
|
||||
{
|
||||
queryParams.Add("runnerVersion", runnerVersion);
|
||||
}
|
||||
if (os != null)
|
||||
{
|
||||
queryParams.Add("os", os);
|
||||
}
|
||||
if (architecture != null)
|
||||
{
|
||||
queryParams.Add("architecture", architecture);
|
||||
}
|
||||
|
||||
// Body
|
||||
var payload = new Dictionary<string, string>
|
||||
{
|
||||
["runnerRequestId"] = runnerRequestId,
|
||||
};
|
||||
var requestContent = new ObjectContent<Dictionary<string, string>>(payload, new VssJsonMediaTypeFormatter(true));
|
||||
|
||||
// POST
|
||||
var result = await SendAsync<object>(
|
||||
new HttpMethod("POST"),
|
||||
requestUri: requestUri,
|
||||
queryParameters: queryParams,
|
||||
content: requestContent,
|
||||
readErrorBody: true,
|
||||
cancellationToken: cancellationToken);
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryParseErrorBody(result.ErrorBody, out BrokerError brokerError))
|
||||
{
|
||||
switch (brokerError.ErrorKind)
|
||||
{
|
||||
case BrokerErrorKind.RunnerNotFound:
|
||||
throw new RunnerNotFoundException(brokerError.Message);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception($"Failed to acknowledge runner request. Request to {requestUri} failed with status: {result.StatusCode}. Error message {result.Error}");
|
||||
}
|
||||
|
||||
private static bool TryParseErrorBody(string errorBody, out BrokerError error)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(errorBody))
|
||||
|
||||
@@ -567,193 +567,5 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_HostedRunnerCheck_Enabled_GitHubHosted_Success()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_jobEc.Global.Variables.Set(WellKnownDistributedTaskVariables.RunnerEnvironment, "github-hosted");
|
||||
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck, "true");
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
await jobExtension.InitializeJob(_jobEc, _message);
|
||||
|
||||
var postJobSteps = _jobEc.PostJobSteps;
|
||||
Assert.Equal(1, postJobSteps.Count);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("RUNNER_ENVIRONMENT", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_HostedRunnerCheck_Enabled_SelfHosted_ThrowsException()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_jobEc.Global.Variables.Set(WellKnownDistributedTaskVariables.RunnerEnvironment, "self-hosted");
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<ArgumentException>(() => jobExtension.InitializeJob(_jobEc, _message));
|
||||
Assert.Contains("Snapshot workflows must be run on a GitHub Hosted Runner", exception.Message);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("RUNNER_ENVIRONMENT", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_ImageGenPoolCheck_Enabled_ImageGenEnabled_Success()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", "true");
|
||||
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
await jobExtension.InitializeJob(_jobEc, _message);
|
||||
|
||||
var postJobSteps = _jobEc.PostJobSteps;
|
||||
Assert.Equal(1, postJobSteps.Count);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_ImageGenPoolCheck_Enabled_ImageGen_False_ThrowsException()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", "false");
|
||||
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
_jobEc.SetRunnerContext("environment", "github-hosted");
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<ArgumentException>(() => jobExtension.InitializeJob(_jobEc, _message));
|
||||
Assert.Contains("Snapshot workflows must be run a hosted runner with Image Generation enabled", exception.Message);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_ImageGenPoolCheck_Enabled_ImageGen_Missing_ThrowsException()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<ArgumentException>(() => jobExtension.InitializeJob(_jobEc, _message));
|
||||
Assert.Contains("Snapshot workflows must be run a hosted runner with Image Generation enabled", exception.Message);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_BothChecks_Enabled_AllConditionsMet_Success()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", "true");
|
||||
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
// Enable both preflight checks
|
||||
_jobEc.Global.Variables.Set(WellKnownDistributedTaskVariables.RunnerEnvironment, "github-hosted");
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck, "true");
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
await jobExtension.InitializeJob(_jobEc, _message);
|
||||
|
||||
var postJobSteps = _jobEc.PostJobSteps;
|
||||
Assert.Equal(1, postJobSteps.Count);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("RUNNER_ENVIRONMENT", null);
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ public class SnapshotOperationProviderL0
|
||||
Assert.NotNull(actualSnapshot);
|
||||
Assert.Equal(expectedSnapshot.ImageName, actualSnapshot!.ImageName);
|
||||
_ec.Verify(ec => ec.Write(null, $"Request written to: {_snapshotRequestFilePath}"), Times.Once);
|
||||
_ec.Verify(ec => ec.Write(null, $"Image Name: {expectedSnapshot.ImageName} Version: {expectedSnapshot.Version}"), Times.Once);
|
||||
_ec.Verify(ec => ec.Write(null, "This request will be processed after the job completes. You will not receive any feedback on the snapshot process within the workflow logs of this job."), Times.Once);
|
||||
_ec.Verify(ec => ec.Write(null, "If the snapshot process is successful, you should see a new image with the requested name in the list of available custom images when creating a new GitHub-hosted Runner."), Times.Once);
|
||||
_ec.VerifyNoOtherCalls();
|
||||
|
||||
@@ -17,7 +17,7 @@ LAYOUT_DIR="$SCRIPT_DIR/../_layout"
|
||||
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||
DOTNETSDK_VERSION="8.0.413"
|
||||
DOTNETSDK_VERSION="8.0.412"
|
||||
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
||||
RUNNER_VERSION=$(cat runnerversion)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.413"
|
||||
"version": "8.0.412"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.329.0
|
||||
2.328.0
|
||||
|
||||
Reference in New Issue
Block a user