通过 .NET 执行时,GitHub Actions 中出现“错误:无法访问 jarfile”,但可以从命令行运行

问题描述 投票:0回答:1

我有一个数据库,其架构使用 Liquibase 进行管理。我有一个使用该数据库进行持久化的 .NET 应用程序。我有使用 Testcontainers 的集成测试。因此,当这些测试运行时,每个测试套件都会通过 Docker 获取自己的 MySQL 数据库来运行其测试,然后这些数据库将被终止。

Liquibase 没有与 .NET 的本机集成,因此为了运行数据库迁移,我在测试容器可用后从 .NET 调用 Liquibase CLI。这在本地工作得很好,但是当我尝试将其放在 GitHub Actions 中时遇到问题:

jobs:
  build-app:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
    - name: Configure AWS CLI
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: eu-west-2
    - name: Checkout
      uses: actions/checkout@v4
    - name: Setup .NET Core
      uses: actions/[email protected]
      with:
        dotnet-version: 6.0.x
    - name: Setup Java
      uses: actions/setup-java@v2
      with:
        distribution: 'adopt'
        java-version: '11'
    - name: Install Liquibase
      run: |
        mkdir liquibase
        chmod +w liquibase
        wget https://github.com/liquibase/liquibase/releases/download/v4.26.0/liquibase-4.26.0.tar.gz
        tar -xzf liquibase-4.26.0.tar.gz -C liquibase
        echo "LIQUIBASE_HOME=${GITHUB_WORKSPACE}/liquibase/liquibase" >> $GITHUB_ENV
        
        chmod -R 755 liquibase
        
        liquibase/liquibase --version
    - name: Login to AWS CodeArtifact
      run: |
          aws codeartifact login --tool dotnet --repository ${{ secrets.AWS_CODEARTIFACT_REPOSITORY }} --domain ${{ secrets.AWS_CODEARTIFACT_DOMAIN }} --domain-owner ${{ secrets.AWS_CODEARTIFACT_ACCOUNT_NUMBER }}
    - name: Restore
      uses: cake-build/cake-action@v2
      with:
        target: Restore
    - name: Build
      uses: cake-build/cake-action@v2
      with:
        target: Build-CI
        arguments: |
          versionNumber: ${{inputs.version}}
    - name: Configure AWS CLI
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: ${{ secrets.INTEGRATION_RUNNER_AWS_ACCESS_KEY }}
        aws-secret-access-key: ${{ secrets.INTEGRATION_RUNNER_AWS_SECRET_ACCESS_KEY }}
        aws-region: eu-west-2
        role-to-assume: ${{ secrets.INTEGRATION_RUNNER_ROLE_ARN }}
    - name: Run tests
      uses: cake-build/cake-action@v2
      with:
        target: Test-CI

Install Liquibase
步骤中对 liquibase/liquibase --version 的调用运行良好,因此我知道 Liquibase 已正确安装。然而,当我从 .NET 调用 Liquibase 时,我收到以下错误:

Error: Unable to access jarfile /home/runner/work/MyProject/WorkingDirectory/liquibase/liquibase/internal/lib/liquibase-core.jar

这个文件是存在的,所以不是路径问题。执行此操作的 .NET 代码是:

private void RunLiquibaseChangesets()
    {
        const string changelog = "db/root-changelog.xml";
        var (username, password, databaseName) = DeconstructConnectionString(_dbContainer.GetConnectionString());
        var url = $"jdbc:mysql://localhost:{_dbContainer.GetMappedPublicPort(ContainerPortNumber)}/{databaseName}";
        var arguments =
            $"update --url={url} --username={username} --password={password} --changeLogFile={changelog} --contexts=test-data";
        var fileName = Environment.GetEnvironmentVariable("LIQUIBASE_HOME") ?? throw new InvalidOperationException(
            "LIQUIBASE_HOME environment variable not set. Please set it to the liquibase installation directory.");
        var rootDirectory = Environment.GetEnvironmentVariable("GITHUB_WORKSPACE") ??
                            Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "..");

        var startInfo = new ProcessStartInfo
        {
            FileName = fileName,
            Arguments = arguments,
            WorkingDirectory = rootDirectory,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        using var process = new Process();
        process.StartInfo = startInfo;
        process.Start();

        // Use StringBuilder to capture output
        var outputBuilder = new StringBuilder();
        var errorBuilder = new StringBuilder();

        // Handle the output events
        process.OutputDataReceived += (_, args) => outputBuilder.AppendLine(args.Data);
        process.ErrorDataReceived += (_, args) => errorBuilder.AppendLine(args.Data);

        // Start reading output and error asynchronously
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        var exited = process.WaitForExit(10000);
        
        Console.WriteLine("----------------- Liquibase Output Start -----------------");
        Console.WriteLine(outputBuilder.ToString());
        Console.WriteLine("----------------- Liquibase Output End -----------------");
        
        Console.WriteLine("----------------- Liquibase Error Start -----------------");
        Console.WriteLine(errorBuilder.ToString());
        Console.WriteLine("----------------- Liquibase Error End -----------------");

        // Check to see if the process has exited.
        if (!exited)
        {
            throw new InvalidOperationException($"Process did not exit: Output: {outputBuilder} Error: {errorBuilder}");
        }
    }

我怀疑这是权限,但我已通过

chmod
授予了完全权限,所以我不知道下一步要尝试什么。

java c# .net github-actions liquibase
1个回答
0
投票

所以事实证明

LIQUIBASE_HOME
对 Liquibase 有一些特殊的意义,尽管它没有在我能找到的任何地方列出。所以我通过使用
LIQUIBASE_INSTALL_DIR
来解决这个问题。

感谢@jonrsharpe将我推向正确的方向。

© www.soinside.com 2019 - 2024. All rights reserved.