Implementation for accessing CodeBuild AWS CodeBuild

AWS CodeBuild is a fully-managed build service in the cloud. AWS CodeBuild compiles your source code, runs unit tests, and produces artifacts that are ready to deploy. AWS CodeBuild eliminates the need to provision, manage, and scale your own build servers. It provides prepackaged build environments for the most popular programming languages and build tools such as Apach Maven, Gradle, and more. You can also fully customize build environments in AWS CodeBuild to use your own build tools. AWS CodeBuild scales automatically to meet peak build requests, and you pay only for the build time you consume. For more information about AWS CodeBuild, see the AWS CodeBuild User Guide.

AWS CodeBuild supports these operations:

  • BatchGetProjects: Gets information about one or more build projects. A build project defines how AWS CodeBuild will run a build. This includes information such as where to get the source code to build, the build environment to use, the build commands to run, and where to store the build output. A build environment represents a combination of operating system, programming language runtime, and tools that AWS CodeBuild will use to run a build. Also, you can add tags to build projects to help manage your resources and costs.

  • CreateProject: Creates a build project.

  • DeleteProject: Deletes a build project.

  • ListProjects: Gets a list of build project names, with each build project name representing a single build project.

  • UpdateProject: Changes the settings of an existing build project.

  • BatchGetBuilds: Gets information about one or more builds.

  • ListBuilds: Gets a list of build IDs, with each build ID representing a single build.

  • ListBuildsForProject: Gets a list of build IDs for the specified build project, with each build ID representing a single build.

  • StartBuild: Starts running a build.

  • StopBuild: Attempts to stop running a build.

  • ListCuratedEnvironmentImages: Gets information about Docker images that are managed by AWS CodeBuild.

Inheritance: AmazonServiceClient, IAmazonCodeBuild
        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);
        }