Skip to content
On this page

GitHub Actions虚拟环境

GitHub Actions提供了一系列预配置的虚拟环境(Virtual Environments),这些环境被称为运行器(Runners)。每个虚拟环境都预装了特定的操作系统、工具和软件包,用于执行工作流中的作业。

虚拟环境概述

GitHub托管的运行器

GitHub提供三种主要的操作系统环境:

  • Ubuntu:最新的Ubuntu LTS版本
  • Windows:Windows Server版本
  • macOS:macOS最新版本
yaml
# .github/workflows/virtual-environments.yml
name: Virtual Environments Example

on: [push]

jobs:
  ubuntu-example:
    runs-on: ubuntu-latest
    steps:
      - name: Ubuntu environment info
        run: |
          echo "OS: $(uname -s)"
          echo "Version: $(lsb_release -a)"
  
  windows-example:
    runs-on: windows-latest
    steps:
      - name: Windows environment info
        run: |
          echo $env:OS
          $PSVersionTable
  
  macos-example:
    runs-on: macos-latest
    steps:
      - name: macOS environment info
        run: |
          sw_vers
          uname -a

Ubuntu虚拟环境

Ubuntu版本和支持

yaml
jobs:
  ubuntu-versions:
    strategy:
      matrix:
        os: [ubuntu-22.04, ubuntu-20.04]  # 不再支持ubuntu-18.04
    runs-on: ${{ matrix.os }}
    steps:
      - name: Check Ubuntu version
        run: |
          echo "Ubuntu version: $(lsb_release -rs)"
          echo "Codename: $(lsb_release -cs)"
          echo "Kernel: $(uname -r)"

Ubuntu环境预装软件

yaml
jobs:
  check-ubuntu-software:
    runs-on: ubuntu-latest
    steps:
      - name: Check pre-installed software
        run: |
          # 版本管理工具
          echo "rbenv: $(which rbenv)"
          echo "nvm: $(which nvm)"
          echo "sdkman: $(which sdkman)"
          
          # 语言运行时
          echo "Node.js: $(node --version)"
          echo "Python: $(python3 --version)"
          echo "Java: $(java -version 2>&1 | head -1)"
          echo "Ruby: $(ruby --version)"
          echo "Go: $(go version)"
          echo "PHP: $(php --version | head -1)"
          echo "Perl: $(perl --version | head -2 | tail -1)"
          
          # 构建工具
          echo "GCC: $(gcc --version | head -1)"
          echo "Clang: $(clang --version | head -1)"
          echo "CMake: $(cmake --version | head -1)"
          echo "Make: $(make --version | head -1)"
          
          # 容器工具
          echo "Docker: $(docker --version)"
          echo "Docker Compose: $(docker-compose --version)"
          
          # 版本控制系统
          echo "Git: $(git --version)"
          echo "Mercurial: $(hg --version)"
          
          # 数据库客户端
          echo "PostgreSQL: $(psql --version)"
          echo "MySQL: $(mysql --version)"
          echo "SQLite: $(sqlite3 --version)"

Ubuntu环境特定配置

yaml
jobs:
  ubuntu-configuration:
    runs-on: ubuntu-latest
    steps:
      - name: Check Ubuntu configuration
        run: |
          # 系统信息
          echo "System: $(uname -a)"
          echo "Architecture: $(uname -m)"
          
          # 磁盘空间
          df -h
          
          # 内存信息
          free -h
          
          # CPU信息
          nproc
          lscpu | head -10
          
          # 环境变量
          echo "Home: $HOME"
          echo "Tmp: $TMPDIR"
          echo "PATH: $PATH"

Windows虚拟环境

Windows版本和支持

yaml
jobs:
  windows-versions:
    runs-on: windows-latest  # 当前是windows-2022
    steps:
      - name: Check Windows version
        run: |
          $PSVersionTable
          Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, WindowsBuildLabEx

Windows环境预装软件

yaml
jobs:
  check-windows-software:
    runs-on: windows-latest
    steps:
      - name: Check pre-installed software
        shell: pwsh
        run: |
          # .NET Framework
          Write-Output ".NET Framework:"
          Get-ChildItem 'HKLM:\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP' -Recurse |
          Get-ItemProperty -Name Version, CBS -ErrorAction SilentlyContinue |
          Where-Object { $_.PSChildName -Match '^(?!S)\\p{L}' } |
          Select-Object PSChildName, Version
          
          # .NET Core/.NET
          Write-Output "`n.NET SDK versions:"
          dotnet --list-sdks
          
          # Node.js
          Write-Output "`nNode.js: $(node --version)"
          
          # Python
          Write-Output "Python: $(python --version)"
          Write-Output "Python3: $(python3 --version)"
          
          # Java
          Write-Output "Java: $(java -version 2>&1 | Select-Object -First 1)"
          
          # PowerShell
          Write-Output "PowerShell: $($PSVersionTable.PSVersion)"
          
          # Git
          Write-Output "Git: $(git --version)"
          
          # Docker
          Write-Output "Docker: $(docker --version)"
          
          # Chocolatey
          Write-Output "Chocolatey: $(choco --version)"

Windows环境特定配置

yaml
jobs:
  windows-configuration:
    runs-on: windows-latest
    steps:
      - name: Check Windows configuration
        shell: pwsh
        run: |
          # 系统信息
          systeminfo | Select-String "OS Name", "OS Version", "System Type"
          
          # 磁盘空间
          Get-WmiObject -Class Win32_LogicalDisk | Select-Object DeviceID, Size, FreeSpace
          
          # 内存信息
          Get-WmiObject -Class Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum | ForEach-Object {"$([math]::Round($_.Sum / 1GB, 2)) GB RAM"}
          
          # 环境变量
          Write-Output "TEMP: $env:TEMP"
          Write-Output "USERPROFILE: $env:USERPROFILE"
          Write-Output "PATH: $env:PATH"

macOS虚拟环境

macOS版本和支持

yaml
jobs:
  macos-versions:
    runs-on: macos-latest  # 当前是macos-13
    steps:
      - name: Check macOS version
        run: |
          sw_vers
          uname -a
          system_profiler SPSoftwareDataType | grep "System Version"

macOS环境预装软件

yaml
jobs:
  check-macos-software:
    runs-on: macos-latest
    steps:
      - name: Check pre-installed software
        run: |
          # Xcode Command Line Tools
          echo "Xcode CLT: $(xcode-select --print-path)"
          
          # Homebrew
          echo "Homebrew: $(brew --version)"
          
          # Languages
          echo "Node.js: $(node --version)"
          echo "Python: $(python3 --version)"
          echo "Java: $(java -version 2>&1 | head -1)"
          echo "Ruby: $(ruby --version)"
          echo "Go: $(go version)"
          echo "Swift: $(swift --version)"
          
          # Build tools
          echo "GCC: $(gcc --version | head -1)"
          echo "Clang: $(clang --version | head -1)"
          echo "Make: $(make --version | head -1)"
          
          # Version control
          echo "Git: $(git --version)"
          
          # Package managers
          echo "Homebrew packages:"
          brew list | head -10

macOS环境特定配置

yaml
jobs:
  macos-configuration:
    runs-on: macos-latest
    steps:
      - name: Check macOS configuration
        run: |
          # 系统信息
          uname -a
          sysctl hw.ncpu hw.memsize
          
          # 磁盘空间
          df -h
          
          # 环境变量
          echo "HOME: $HOME"
          echo "TMPDIR: $TMPDIR"
          echo "PATH: $PATH"

环境变量和路径

预定义环境变量

yaml
jobs:
  environment-variables:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - name: Display environment variables
        run: |
          case $RUNNER_OS in
            Linux)
              echo "OS: Linux"
              echo "Temp: $RUNNER_TEMP"
              echo "Tool Cache: $RUNNER_TOOL_CACHE"
              echo "Workspace: $GITHUB_WORKSPACE"
              ;;
            Windows)
              echo "OS: Windows"
              echo "Temp: $env:RUNNER_TEMP"
              echo "Tool Cache: $env:RUNNER_TOOL_CACHE"
              echo "Workspace: $env:GITHUB_WORKSPACE"
              ;;
            macOS)
              echo "OS: macOS"
              echo "Temp: $RUNNER_TEMP"
              echo "Tool Cache: $RUNNER_TOOL_CACHE"
              echo "Workspace: $GITHUB_WORKSPACE"
              ;;
          esac
        shell: bash

工具缓存

GitHub提供工具缓存来加速安装过程:

yaml
jobs:
  tool-cache-example:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js with caching
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'  # 启用npm依赖缓存
      
      - name: Setup Python with caching
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
          cache: 'pip'  # 启用pip依赖缓存
      
      - name: Setup Java with caching
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
          cache: 'maven'  # 启用Maven依赖缓存

自定义环境配置

安装额外软件

yaml
jobs:
  custom-software:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - name: Install custom software on Ubuntu
        if: matrix.os == 'ubuntu-latest'
        run: |
          sudo apt-get update
          sudo apt-get install -y redis-tools
          redis-cli --version
      
      - name: Install custom software on Windows
        if: matrix.os == 'windows-latest'
        run: |
          choco install -y redis-64
          redis-cli --version
        shell: cmd
      
      - name: Install custom software on macOS
        if: matrix.os == 'macos-latest'
        run: |
          brew install redis
          redis-cli --version

使用Docker容器

yaml
jobs:
  docker-container:
    runs-on: ubuntu-latest
    container:
      image: node:18-alpine
      env:
        NODE_ENV: production
    steps:
      - name: Use Docker container
        run: |
          echo "Running in Node.js container"
          node --version
          npm --version

硬件规格

运行器硬件规格

yaml
jobs:
  hardware-specs:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - name: Check hardware specs
        run: |
          case $RUNNER_OS in
            Linux)
              echo "CPU cores: $(nproc)"
              echo "Memory: $(free -g | awk '/^Mem:/{print $2}') GB"
              echo "Disk space: $(df -BG / --output=avail | tail -1 | tr -d ' ') GB"
              ;;
            Windows)
              echo "CPU cores: $env:NUMBER_OF_PROCESSORS"
              $memory = Get-CimInstance Win32_ComputerSystem | Select-Object TotalPhysicalMemory
              echo "Memory: $([math]::Round($memory.TotalPhysicalMemory / 1GB)) GB"
              ;;
            macOS)
              echo "CPU cores: $(sysctl -n hw.ncpu)"
              echo "Memory: $(sysctl -n hw.memsize | awk '{print int($1/1024/1024/1024)}') GB"
              echo "Disk space: $(df -g / | awk 'NR==2 {print $4}') GB"
              ;;
          esac

网络和防火墙

网络访问

yaml
jobs:
  network-access:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - name: Test network connectivity
        run: |
          case $RUNNER_OS in
            Linux|macOS)
              ping -c 3 google.com
              curl -I https://httpbin.org/status/200
              ;;
            Windows)
              ping -n 3 google.com
              Invoke-RestMethod -Uri https://httpbin.org/status/200
              ;;
          esac

时区和区域设置

时区配置

yaml
jobs:
  timezone-info:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - name: Check timezone
        run: |
          case $RUNNER_OS in
            Linux)
              timedatectl
              echo "Current time: $(date)"
              ;;
            Windows)
              tzutil /g
              echo "Current time: $(Get-Date)"
              ;;
            macOS)
              systemsetup -gettimezone
              echo "Current time: $(date)"
              ;;
          esac

限制和配额

使用限制

GitHub Actions有以下限制:

  • 执行时间:每个作业最多运行6小时
  • 存储空间:每个仓库最多500MB
  • 并发作业:免费账户有限制,付费账户有更高的限制
  • 网络带宽:有合理的使用限制
yaml
jobs:
  check-limits:
    runs-on: ubuntu-latest
    steps:
      - name: Demonstrate timeout handling
        run: |
          # 模拟长时间运行的任务
          for i in {1..360}; do  # 最多运行360次,每次10秒 = 60分钟
            echo "Running iteration $i at $(date)"
            sleep 10
            
            # 检查是否接近超时
            if [ $i -gt 1080 ]; then  # 1080 * 10秒 = 3小时
              echo "Approaching timeout, stopping gracefully"
              break
            fi
          done
        timeout-minutes: 360  # 6小时超时

自托管运行器

自托管运行器配置

除了GitHub托管的运行器,还可以使用自托管运行器:

yaml
jobs:
  self-hosted-example:
    runs-on: [self-hosted, linux, x64]  # 使用自定义标签
    steps:
      - name: Run on self-hosted runner
        run: |
          echo "Running on self-hosted runner"
          echo "This runner has custom configuration"
          # 可以访问内部网络和服务

最佳实践

1. 选择合适的环境

yaml
# 根据项目需求选择环境
jobs:
  cross-platform-tests:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - name: Run tests on ${{ matrix.os }}
        run: npm test

2. 利用缓存

yaml
jobs:
  cached-build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Cache dependencies
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
      
      - name: Install and build
        run: |
          npm ci
          npm run build

3. 环境特定优化

yaml
jobs:
  optimized-for-os:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    steps:
      - name: OS-specific optimizations
        run: |
          if [ "$RUNNER_OS" == "Linux" ]; then
            echo "Running on Linux - optimizing for performance"
            export NODE_OPTIONS="--max-old-space-size=4096"
          elif [ "$RUNNER_OS" == "Windows" ]; then
            echo "Running on Windows - adjusting for Windows specifics"
            # Windows-specific configurations
          fi
          
          npm run build

通过理解GitHub Actions虚拟环境的特性和配置,可以更好地利用这些环境来构建、测试和部署应用程序,同时确保跨平台兼容性。