export async function run()

in src/index.ts [56:264]


export async function run(): Promise<void> {
    const serviceName = getInput('service', { required: true });
    const sourceConnectionArn = getInput('source-connection-arn', { required: false });
    const accessRoleArn = getInput('access-role-arn', { required: false });
    const repoUrl = getInput('repo', { required: false });
    const imageUri = getInput('image', { required: false });
    const runtime = getInput('runtime', { required: false });
    const buildCommand = getInput('build-command', { required: false });
    const startCommand = getInput('start-command', { required: false });
    const port = getInputInt('port', 80);
    const waitForService = getInput('wait-for-service-stability', { required: false }) || "false";

    try {
        // Check for service type
        const isImageBased = !!imageUri;

        // Validations - AppRunner Service name
        if (!serviceName)
            throw new Error('AppRunner service name cannot be empty');

        // Image URI required if the service is docker registry based
        if (isImageBased && repoUrl)
            throw new Error('Either docker image registry or code repository expected, not both');

        // Mandatory check for source code based AppRunner
        if (!isImageBased) {
            if (!sourceConnectionArn || !repoUrl || !runtime
                || !buildCommand
                || !startCommand)
                throw new Error('Connection ARN, Repository URL, Runtime, build and start command are expected');


            // Runtime enum check
            if (!supportedRuntime.includes(runtime))
                throw new Error(`Unexpected value passed in runtime ${runtime} only supported values are: ${JSON.stringify(supportedRuntime)}`);
        } else {            
            // IAM Role check for ECR based AppRunner
            if (!accessRoleArn)
                throw new Error(`Access role ARN is required for ECR based AppRunner`);
        }

        // Defaults
        // Region - us-east-1
        const region = getInput('region', { required: false }) || 'us-east-1';

        // Branch - master
        let branch = getInput('branch', { required: false }) || 'master';

        // Get branch details from refs
        if (branch.startsWith("refs/")) {
            branch = branch.split("/")[2];
        }

        // CPU - 1
        const cpu = getInputInt('cpu', 1);

        // Memory - 2
        const memory = getInputInt('memory', 2);

        // AppRunner client
        const client = new AppRunnerClient({ region: region });

        // Check whether service exists and get ServiceArn
        let serviceArn = await getServiceArn(client, serviceName);

        // New service or update to existing service
        let serviceId: string | undefined = undefined;
        if (!serviceArn) {
            info(`Creating service ${serviceName}`);
            const command = new CreateServiceCommand({
                ServiceName: serviceName,
                InstanceConfiguration: {
                    Cpu: `${cpu} vCPU`,
                    Memory: `${memory} GB`,
                },
                SourceConfiguration: {}
            });
            if (isImageBased) {
                // Image based set docker registry details
                command.input.SourceConfiguration = {
                    AuthenticationConfiguration: {
                        AccessRoleArn: accessRoleArn
                    },
                    ImageRepository: {
                        ImageIdentifier: imageUri,
                        ImageRepositoryType: getImageType(imageUri),
                        ImageConfiguration: {
                            Port: `${port}`
                        }
                    }
                };
            } else {
                // Source code based set source code details
                command.input.SourceConfiguration = {
                    AuthenticationConfiguration: {
                        ConnectionArn: sourceConnectionArn
                    },
                    AutoDeploymentsEnabled: true,
                    CodeRepository: {
                        RepositoryUrl: repoUrl,
                        SourceCodeVersion: {
                            Type: "BRANCH",
                            Value: branch
                        },
                        CodeConfiguration: {
                            ConfigurationSource: "API",
                            CodeConfigurationValues: {
                                Runtime: runtime,
                                BuildCommand: buildCommand,
                                StartCommand: startCommand,
                                Port: `${port}`
                            }
                        }
                    }
                };
            }
            const createServiceResponse = await client.send(command);
            serviceId = createServiceResponse.Service?.ServiceId;
            info(`Service creation initiated with service ID - ${serviceId}`)
            serviceArn = createServiceResponse.Service?.ServiceArn;
        } else {
            info(`Updating existing service ${serviceName}`);
            const command = new UpdateServiceCommand({
                ServiceArn: serviceArn,
                SourceConfiguration: {}
            });
            if (isImageBased) {
                // Update only in case of docker registry based service
                command.input.SourceConfiguration = {
                    AuthenticationConfiguration: {
                        AccessRoleArn: accessRoleArn
                    },
                    ImageRepository: {
                        ImageIdentifier: imageUri,
                        ImageRepositoryType: getImageType(imageUri),
                        ImageConfiguration: {
                            Port: `${port}`
                        }
                    }
                }
            } else {
                // Source code based set source code details
                command.input.SourceConfiguration = {
                    AuthenticationConfiguration: {
                        ConnectionArn: sourceConnectionArn
                    },
                    CodeRepository: {
                        RepositoryUrl: repoUrl,
                        SourceCodeVersion: {
                            Type: "BRANCH",
                            Value: branch
                        },
                        CodeConfiguration: {
                            ConfigurationSource: "API",
                            CodeConfigurationValues: {
                                Runtime: runtime,
                                BuildCommand: buildCommand,
                                StartCommand: startCommand,
                                Port: `${port}`
                            }
                        }
                    }
                };
            }
            const updateServiceResponse = await client.send(command);
            serviceId = updateServiceResponse.Service?.ServiceId;
            info(`Service update initiated with operation ID - ${serviceId}`)
            serviceArn = updateServiceResponse.Service?.ServiceArn;
        }

        // Set output
        setOutput('service-id', serviceId);

        // Wait for service to be stable (if required)
        if (waitForService === "true") {
            let attempts = 0;
            let status = OPERATION_IN_PROGRESS;
            info(`Waiting for the service ${serviceId} to reach stable state`);
            while (status === OPERATION_IN_PROGRESS && attempts < MAX_ATTEMPTS) {
                const describeServiceResponse = await client.send(new DescribeServiceCommand({
                    ServiceArn: serviceArn
                }));

                status = describeServiceResponse.Service?.Status ?? OPERATION_IN_PROGRESS;
                if (status !== OPERATION_IN_PROGRESS)
                    break;

                // Wait for 5 seconds and re-try
                await sleep(5000);
                attempts++;
            }

            // Throw error if service has not reached an end state
            if (attempts >= MAX_ATTEMPTS)
                throw new Error(`Service did not reach stable state after ${attempts} attempts`);
            else
                info(`Service ${serviceId} has reached the stable state ${status}`);
        } else {
            info(`Service ${serviceId} has started creation. Watch for creation progress in AppRunner console`);
        }
    } catch (error) {
        if (error instanceof Error) {
            setFailed(error.message);
            debug(error.stack ?? 'no stack info');
        } else {
            setFailed(JSON.stringify(error));
        }
    }
}