static async Task <string> Build(BuildRequest request)
        {
            var client = new Amazon.CodeBuild.AmazonCodeBuildClient();

            //check if there is a successful build with that version number
            //if there is, don't build a new one

            var validBuilds = await client.ListBuildBatchesForProjectAsync(new ListBuildBatchesForProjectRequest()
            {
                ProjectName = request.ProjectName,
                Filter      = new BuildBatchFilter()
                {
                    Status = StatusType.SUCCEEDED
                }
            });

            var detail = await client.BatchGetBuildBatchesAsync(new BatchGetBuildBatchesRequest()
            {
                Ids = validBuilds.Ids
            });

            var reqenv = request.EnvironmentVariablesOverride.ToDictionary(x => x.Name, x => x.Value);

            foreach (var build in detail.BuildBatches)
            {
                var    buildenv = build.Environment.EnvironmentVariables.ToDictionary(x => x.Name, x => x.Value);
                string reqVersion;
                reqenv.TryGetValue("Version", out reqVersion);
                string buildVersion;
                buildenv.TryGetValue("Version", out buildVersion);
                if (reqVersion == buildVersion)
                {
                    Console.WriteLine("Found old version... returning that arn");
                    return(build.Arn);
                }
            }

            var result = await client.StartBuildBatchAsync(new StartBuildBatchRequest()
            {
                EnvironmentVariablesOverride = request.EnvironmentVariablesOverride,
                ProjectName       = request.ProjectName,
                BuildspecOverride = request.BuildspecOverride,
            });

            var arn = result.BuildBatch.Arn;

            return(arn);
        }
        static async Task <string> Wait(string arn, TimeSpan timeout, int maxRetries = 3)
        {
            var            status       = StatusType.IN_PROGRESS;
            var            client       = new Amazon.CodeBuild.AmazonCodeBuildClient();
            var            waitTime     = TimeSpan.Parse("00:00:10");
            bool           isComplete   = false;
            bool           isTimedOut   = false;
            bool           isSuccessful = false;
            DateTimeOffset start        = DateTimeOffset.Now;
            int            retry        = 0;

            while (!isComplete && !isTimedOut)
            {
                var result = await client.BatchGetBuildBatchesAsync(new BatchGetBuildBatchesRequest()
                {
                    Ids = new List <string>()
                    {
                        arn
                    }
                });

                isComplete   = result.BuildBatches.All(x => x.Complete);
                isSuccessful = result.BuildBatches.All(x => x.BuildBatchStatus == StatusType.SUCCEEDED);
                status       = result.BuildBatches.FirstOrDefault()?.BuildBatchStatus ?? StatusType.IN_PROGRESS;
                isTimedOut   = (DateTimeOffset.Now >= start.Add(timeout));
                if (!isComplete)
                {
                    Console.WriteLine("Not complete... waiting " + waitTime);
                    await Task.Delay(waitTime);
                }

                if (isComplete && !isSuccessful && !isTimedOut && retry < maxRetries)
                {
                    //retry
                    retry += 1;
                    var retryResult = await client.RetryBuildBatchAsync(new RetryBuildBatchRequest()
                    {
                        Id               = arn,
                        RetryType        = RetryBuildBatchType.RETRY_FAILED_BUILDS,
                        IdempotencyToken = Guid.NewGuid().ToString(),
                    });

                    isComplete = false;
                    start      = DateTimeOffset.UtcNow;
                    arn        = retryResult.BuildBatch.Arn;
                }
            }

            if (isTimedOut)
            {
                status = StatusType.TIMED_OUT;
                Console.WriteLine("::error::Timed out");
                Console.WriteLine("Timed out");
            }

            if (!isComplete)
            {
                Console.WriteLine("Complete");
                Console.WriteLine("::debug::Complete");
                Console.WriteLine("Successful: " + isSuccessful);
            }
            Console.WriteLine("::debug::Status " + status);
            return(status);
        }