bugsnag / bugsnag-android-gradle-plugin

Gradle plugin for BugSnag which uploads ProGuard, DexGuard and NDK mapping files, and sends build notifications
https://docs.bugsnag.com/build-integrations/gradle/
MIT License
70 stars 38 forks source link

Plugin fails the build when Git executable is not available #539

Open azabost opened 1 year ago

azabost commented 1 year ago

Describe the bug

Bugsnag Android Gradle Plugin seems to require Git executable to be available and will fail otherwise, which is surprising and contradictory to the documentation which literally says: "values are automatically detected if Git is installed", so it sounds like it shouldn't fail if there is no Git.

When I used a Docker image without the Git executable in my GitHub Actions pipeline, the Bugsnag plugin's task failed:

Execution failed for task ':app:bugsnagRelease-releaseTask'.
> Error while evaluating property 'gitVersion' of task ':app:bugsnagRelease-releaseTask'.
   > A problem occurred starting process 'command 'git''

Many Docker images don't include Git because in CI environment both the repository and the Git info such as commit SHA (i.e. revision) etc. are available via environment variables (example).

Therefore, I decided to provide the necessary information manually in my app/build.gradle.kts file:

android {
    bugsnag {
        if (System.getenv("CI").toBoolean()) {
            sourceControl {
                provider.set("github-enterprise")
                repository.set("https://some.url/to-my/repo")
                revision.set(System.getenv("GITHUB_SHA"))
            }
        }
    }
}

Unfortunately, it didn't seem to help and the plugin's task was still failing. Maybe my if condition was wrong (I didn't check) but judging from this code, I thought the problem may lie in the lack of adequate logic on the plugin's side. It looks like the Git commands are being executed regardless of Git availability or manual sourceControl configuration.

I ended up creating another Docker image with Git installed and that solved the problem for me, but IMO Bugsnag plugin shouldn't require Git to be present.

If you would like to try it yourself, the Docker images I was using are here:

Steps to reproduce

  1. Apply Bugsnag Android Gradle Plugin
  2. Either configure or don't configure bugsnag.sourceControl block - probably doesn't matter
  3. Run the release build variant on a machine without git executable
  4. See error

Environment

Gradle build error with stacktrace

Click here to expand: ``` > Task :app:bugsnagRelease-releaseTask FAILED > Task :app:generateBugsnag-releaseMapping 0 problems were found storing the configuration cache. FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:bugsnagRelease-releaseTask'. > Error while evaluating property 'gitVersion' of task ':app:bugsnagRelease-releaseTask'. > A problem occurred starting process 'command 'git'' * Try: > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. See the complete report at file:///__w/MyApp/MyApp/build/reports/configuration-cache/54wp53pq39e6fbw1bdjjhxy2x/d7gy44vhzne2w65yh4m77yww3/configuration-cache-report.html 795 actionable tasks: 795 executed Configuration cache entry stored. * Exception is: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:bugsnagRelease-releaseTask'. at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:38) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73) at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:146) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:135) at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52) at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:337) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:324) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:317) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49) Caused by: org.gradle.process.internal.ExecException: A problem occurred starting process 'command 'git'' at org.gradle.process.internal.DefaultExecHandle.execExceptionFor(DefaultExecHandle.java:241) at org.gradle.process.internal.DefaultExecHandle.setEndStateInfo(DefaultExecHandle.java:218) at org.gradle.process.internal.DefaultExecHandle.failed(DefaultExecHandle.java:370) at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:87) at org.gradle.internal.operations.CurrentBuildOperationPreservingRunnable.run(CurrentBuildOperationPreservingRunnable.java:42) ... 2 more Caused by: net.rubygrapefruit.platform.NativeException: Could not start 'git' at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:27) at net.rubygrapefruit.platform.internal.WrapperProcessLauncher.start(WrapperProcessLauncher.java:36) at org.gradle.process.internal.ExecHandleRunner.startProcess(ExecHandleRunner.java:98) at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:71) ... 3 more Caused by: java.io.IOException: Cannot run program "git" (in directory "/__w/MyApp/MyApp"): error=2, No such file or directory at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25) ... 6 more Caused by: java.io.IOException: error=2, No such file or directory ... 7 more ```
clr182 commented 1 year ago

Hi @azabost

I have raised this as an item on our backlog. We will be sure to keep you informed of any updates, however I presently do not have a firm ETA on the release.