{"id":13505591,"url":"https://github.com/cdklabs/aws-delivlib","last_synced_at":"2026-02-04T23:01:50.677Z","repository":{"id":38094615,"uuid":"153164192","full_name":"cdklabs/aws-delivlib","owner":"cdklabs","description":"setup and manage continuous delivery pipelines for code libraries in multiple languages","archived":false,"fork":false,"pushed_at":"2024-05-23T00:31:54.000Z","size":9495,"stargazers_count":367,"open_issues_count":0,"forks_count":34,"subscribers_count":20,"default_branch":"main","last_synced_at":"2024-05-23T02:13:11.335Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cdklabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-15T18:42:08.000Z","updated_at":"2024-05-28T03:42:15.402Z","dependencies_parsed_at":"2024-01-02T01:40:05.138Z","dependency_job_id":"e211cd50-b252-4aee-b393-858c9aacd3f2","html_url":"https://github.com/cdklabs/aws-delivlib","commit_stats":{"total_commits":1165,"total_committers":40,"mean_commits":29.125,"dds":0.7244635193133047,"last_synced_commit":"02c9391b82b389ddc0fa583ce8346be90b2cf325"},"previous_names":["awslabs/aws-delivlib"],"tags_count":1043,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Faws-delivlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Faws-delivlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Faws-delivlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Faws-delivlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cdklabs","download_url":"https://codeload.github.com/cdklabs/aws-delivlib/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245760988,"owners_count":20667893,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T00:01:10.275Z","updated_at":"2025-12-29T23:09:53.866Z","avatar_url":"https://github.com/cdklabs.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","others"],"sub_categories":[],"readme":"## aws-delivlib\n\n[![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges)\n\n**aws-delivlib** is a fabulous library for defining continuous pipelines for\nbuilding, testing and publishing code libraries through AWS CodeBuild and AWS\nCodePipeline.\n\n**aws-delivlib** is used by the [AWS Cloud Development Kit](https://github.com/awslabs/aws-cdk) and was\ndesigned to support simultaneous delivery of the AWS CDK in multiple programming languages\npackaged via [jsii](https://github.com/awslabs/jsii).\n\n## Pipeline Structure\n\nA delivlib pipeline consists of the following sequential stages. Each stage will\nexecute all tasks concurrently:\n\n```\n+-----------+     +-----------+     +-----------+     +----------------+\n|  Source   +----\u003e+   Build   +----\u003e+   Test    +----\u003e+    Publish     |\n+-----------+     +-----------+     +-----+-----+     +-------+--------+\n                                          |                   |\n                                          v                   v\n                                    +-----+-----+     +-------+-------+\n                                    |   Test1   |     |      npm      |\n                                    +-----------+     +---------------+\n                                    |   Test2   |     |     NuGet     |\n                                    +-----------+     +---------------+\n                                    |   Test3   |     | Maven Central |\n                                    +-----------+     +---------------+\n                                    |    ...    |     |     PyPI      |\n                                    +-----------+     +---------------+\n                                                      |  GitHub Pages |\n                                                      +---------------+\n                                                      |GitHub Releases|\n                                                      +---------------+\n```\n\nThe following sections describe each stage and the configuration options\navailable:\n\n- [aws-delivlib](#aws-delivlib)\n- [Pipeline Structure](#pipeline-structure)\n- [Installation](#installation)\n- [Source](#source)\n  - [`repo`: Source Repository (required)](#repo-source-repository-required)\n  - [`branch`: Source Control Branch (optional)](#branch-source-control-branch-optional)\n- [Pull Request Builds](#pull-request-builds)\n- [Build](#build)\n  - [`buildSpec`: Build Script (optional)](#buildspec-build-script-optional)\n  - [`buildImage`: Build container image (optional)](#buildimage-build-container-image-optional)\n  - [`env`: Build environment variables (optional)](#env-build-environment-variables-optional)\n  - [Other Build Options](#other-build-options)\n- [Tests](#tests)\n- [Publish](#publish)\n  - [npm.js (JavaScript)](#npmjs-javascript)\n  - [NuGet (.NET)](#nuget-net)\n  - [Maven Central (Java)](#maven-central-java)\n  - [PyPI (Python)](#pypi-python)\n  - [GitHub Releases](#github-releases)\n  - [GitHub Pages](#github-pages)\n- [Metrics](#metrics)\n- [Automatic Bumps and Pull Request Builds](#automatic-bumps-and-pull-request-builds)\n  - [GitHub Access](#github-access)\n  - [Automatic Bumps](#automatic-bumps)\n- [Failure Notifications](#failure-notifications)\n- [ECR Mirror](#ecr-mirror)\n- [Contributing](#contributing)\n- [License](#license)\n\n\n## Installation\n\nTo install, use npm / yarn:\n\n```console\n$ npm i aws-delivlib\n```\n\nor:\n\n```console\n$ yarn add aws-delivlib\n```\n\nand import the library to your project:\n\n```ts\nimport delivlib = require('aws-delivlib');\n```\n\nThe next step is to add a pipeline to your app. When you define a pipeline, the\nminimum requirement is to specify the source repository. All other settings are\noptional.\n\n```ts\nconst pipeline = new delivlib.Pipeline(this, 'MyPipeline', {\n  // options\n});\n```\n\nThe following sections will describe the various options available in your\npipeline.\n\nYou can also take a look at the\n[pipeline definition releasing the delivlib library itself](pipeline/delivlib.ts)\nfor a real-world, working example.\n\n## Source\n\nThe only required option when defining a pipeline is to specify a source\nrepository for your project.\n\n### `repo`: Source Repository (required)\n\nThe `repo` option specifies your source code repository for your project. You\ncould use either CodeCommit or GitHub.\n\n#### CodeCommit\n\nTo use an existing repository:\n\n```ts\nimport codecommit = require('@aws-cdk/aws-codecommit');\n\n// import an existing repository\nconst myRepo = codecommit.Repository.fromRepositoryName(this, 'TestRepo',\n  'delivlib-test-repo');\n\n// ...or define a new repository (probably not what you want)\nconst myRepo = new codecommit.Repository(this, 'TestRepo');\n\n// create a delivlib pipeline associated with this codebuild repo\nnew delivlib.Pipeline(this, 'MyPipeline', {\n  repo: new delivlib.CodeCommitRepo(myRepo),\n  // ...\n});\n```\n\n#### GitHub\n\nTo connect to GitHub, you will need to store a [Personal GitHub Access\nToken](https://github.com/settings/tokens) as an SSM Parameter and provide the\nname of the SSM parameter.\n\n```ts\nimport cdk = require('@aws-cdk/core');\n\nnew delivlib.Pipeline(this, 'MyPipeline', {\n  repo: new delivlib.GitHubRepo({\n    repository: 'cdklabs/aws-delivlib',\n    token: cdk.SecretValue.secretsManager('my-github-token'),\n  }),\n  // ...\n})\n```\n\n### `branch`: Source Control Branch (optional)\n\nThe `branch` option can be used to specify the git branch to build from. The\ndefault is `master`.\n\n```ts\nnew delivlib.Pipeline(this, 'MyPipeline', {\n  repo: // ...\n  branch: 'dev',\n})\n```\n\n## Pull Request Builds\n\nPull Request Builds can be used to validate if changes submitted via a pull request\nsuccessfully build and pass tests. They are triggered automatically by GitHub or\nCodeCommit when pull requests are submitted or updated.\n\nKnown in delivlib as AutoBuild, they can be enabled on the Pipeline and further\nconfigured -\n\n```ts\nnew delivlib.Pipeline(this, 'MyPipeline', {\n  // ...\n  autoBuild: true,\n  autoBuildOptions: {\n    publicLogs: true,\n  },\n});\n```\n\nDelivlib also separately exports the `AutoBuild` construct that can be used to configure\nAutoBuild on a project that doesn't have a pipeline associated, or for jobs that can be\nrun outside of a pipeline.\n\n```ts\nnew delivlib.AutoBuild(this, 'MyAutoBuild', {\n  repo: // ...\n});\n```\n\n## Build\n\nThe second stage of a pipeline is to build your code. The following options\nallow you to do customize your build environment and scripts:\n\n### `buildSpec`: Build Script (optional)\n\nThe default behavior will use the `buildspec.yaml` file from the root of your\nsource repository to determine the build steps.\n\nSee the the [buildspec reference documentation](https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html)\nin the CodeBuild User Guide.\n\nNote that if you don't have an \"__artifacts__\" section in your buildspec, you won't\nbe able to run any tests against the build outputs or publish them to package\nmanagers.\n\nIf you wish, you can use the `buildSpec` option, in which case CodeBuild will not\nuse the checked-in `buildspec.yaml`:\n\n```ts\nimport codebuild = require('@aws-cdk/aws-codebuild');\n\nnew delivlib.Pipeline(this, 'MyPipeline', {\n  // ...\n  buildSpec: codebuild.BuildSpec.fromObject({\n    version: '0.2',\n    phases: {\n      build: {\n        commands: [\n          'echo \"Hello, world!\"'\n        ]\n      }\n    },\n    artifacts: {\n      files: [ '**/*' ],\n      'base-directory': 'dist'\n    }\n  }),\n});\n```\n\n### `buildImage`: Build container image (optional)\n\nThe Docker image to use for the build container.\n\nDefault: the default image (if none is specified) is a custom Docker image which\nis provided as part of the [jsii] distribution called [jsii/superchain]. It is\nan environment that supports building libraries that target all programming\nlanguages supported by [jsii]. Find more information on the contents of the\n[jsii/superchain] image on the [jsii] homepage.\n\n[jsii]: https://github.com/aws/jsii\n[jsii/superchain]: https://hub.docker.com/r/jsii/superchain\n\nYou can use the AWS CodeBuild API to specify any Linux/Windows Docker image for\nyour build. Here are some examples:\n\n* `codebuild.LinuxBuildImage.fromDockerRegistry('golang:1.11')` - use an image from Docker Hub\n* `codebuild.LinuxBuildImage.UBUNTU_14_04_OPEN_JDK_9` - OpenJDK 9 available from AWS CodeBuild\n* `codebuild.WindowsBuildImage.WIN_SERVER_CORE_2016_BASE` - Windows Server Core 2016 available from AWS CodeBuild\n* `codebuild.LinuxBuildImage.fromEcrRepository(myRepo)` - use an image from an ECR repository\n\n### `env`: Build environment variables (optional)\n\nAllows adding environment variables to the build environment:\n\n```ts\nnew delivlib.Pipeline(this, 'MyPipeline', {\n  // ...\n  environment: {\n    FOO: 'bar'\n  }\n});\n```\n\n### Other Build Options\n\n* `computeType`: size of the AWS CodeBuild compute capacity (default: SMALL)\n* `privileged`: run in privileged mode (default: `false`)\n\n## Tests\n\nThe third stage of a delivlib pipeline is to execute tests. Tests are executed\nin parallel only after a successful build and can access build artifacts as\ndefined in your `buildspec.yaml`.\n\nThe `pipeline.addTest` method can be used to add tests to your pipeline. Test\nscripts are packaged as part of your delivlib CDK app.\n\n```ts\ndelivlib.addTest('MyTest', {\n  platform: delivlib.ShellPlatform.LinuxUbuntu(), // or `ShellPlatform.Windows()`\n  scriptDirectory: 'path/to/local/directory/with/tests',\n  entrypoint: 'run.sh',\n});\n```\n\n`scriptDirectory` refers to a directory on the local file system which must\ncontain the `entrypoint` file.\nPreferably make this path relative to the current file using `path.join(__dirname, ...)`.\n\nThe test container will be populated the build output artifacts as well as all\nthe files from the test directory.\n\nThen, the entry-point will be executed. If it fails, the test failed.\n\n## Publish\n\nThe last step of the pipeline is to publish your artifacts to one or more\npackage managers. Delivlib is shipped with a bunch of built-in publishing\ntasks, but you could add your own if you like.\n\nTo add a publishing target to your pipeline, you can either use the\n`pipeline.addPublish(publisher)` method or one of the built-in\n`pipeline.publishToXxx` methods. The first option is useful if you wish to\ndefine your own publisher, which is class the implements the\n`delivlib.IPublisher` interface.\n\nBuilt-in publishers are designed to be idempotent: if the artifacts version is\nalready published to the package manager, the publisher __will succeed__. This\nmeans that in order to publish a new version, all you need to do is bump the\nversion of your package artifact (e.g. change `package.json`) and the publisher\nwill kick in.\n\nYou can use the `dryRun: true` option when creating a publisher to tell the\npublisher to do as much as it can without actually making the package publicly\navailable. This is useful for testing.\n\nThe following sections describe how to use each one of the built-in publishers.\n\n### npm.js (JavaScript)\n\nThe method `pipeline.publishToNpm` will add a publisher to your pipeline which\ncan publish JavaScript modules to [npmjs](https://www.npmjs.com/).\n\nThe publisher will search for `js/*.tgz` in your build artifacts and will `npm\npublish` each of them.\n\nTo create npm tarballs, you can use `npm pack` as part of your build and emit\nthem to the `js/` directory in your build artifacts. The version of the module\nis deduced from the name of the tarball.\n\nTo use this publisher, you will first need to store an [npm.js publishing\ntoken](https://docs.npmjs.com/creating-and-viewing-authentication-tokens) in AWS\nSecrets Manager and supply the secret ARN when you add the publisher.\n\n```ts\npipeline.publishToNpm({\n  npmTokenSecret: { secretArn: 'my-npm-token-secret-arn' }\n});\n```\n\n### NuGet (.NET)\n\nThis publisher can publish .NET NuGet packages to [nuget.org](https://www.nuget.org/).\n\nThe publisher will search `dotnet/**/*.nuget` in your build artifacts and will\npublish each package to NuGet. To create .nupkg files, see [Creating NuGet\nPackages](https://docs.microsoft.com/en-us/nuget/create-packages/creating-a-package).\nMake sure you output the artifacts under the `dotnet/` directory.\n\nTo use this publisher, you will first need to store a [NuGet API\nKey](https://www.nuget.org/account/apikeys) with \"Push\" permissions in AWS\nSecrets Manager and supply the secret ARN when you add the publisher.\n\nUse `pipeline.publishToNuGet` will add a publisher to your pipeline:\n\n```ts\npipeline.publishToNuGet({\n  nugetApiKeySecret: { secretArn: 'my-nuget-token-secret-arn' }\n});\n```\n\n#### Assembly Signature\n\n**Important:** Limitations in the `mono` tools restrict the hash algorithms that\ncan be used in the signature to `SHA-1`. This limitation will be removed in the\nfuture.\n\nYou can enable digital signatures for the `.dll` files enclosed in your NuGet\npackages. In order to do so, you need to procure a Code-Signing Certificate\n(also known as a Software Publisher Certificate, or SPC). If you don't have one\nyet, you can refer to\n[Obtaining a new Code Signing Certificate](#obtaining-a-new-code-signing-certificate)\nfor a way to create a new certificate entirely in the Cloud.\n\nIn order to enable code signature, change the way the NuGet publisher is added\nby adding an `ICodeSigningCertificate` for the `codeSign` key (it could be a\n`CodeSigningCertificate` construct, or you may bring your own implementation if\nyou wish to use a pre-existing certificate):\n\n```ts\npipeline.publishToNuGet({\n  nugetApiKeySecret: { secretArn: 'my-nuget-token-secret-arn' },\n  codeSign: codeSigningCertificate\n});\n```\n\n##### Obtaining a new Code Signing Certificate\n\nIf you want to create a new certificate, the `CodeSigningCertificate` construct\nwill provision a new RSA Private Key and emit a Certificate Signing Request in\nan `Output` so you can pass it to your Certificate Authority (CA) of choice:\n1. Add a `CodeSigningCertificate` to your stack:\n    ```ts\n    new delivlib.CodeSigningCertificate(stack, 'CodeSigningCertificate', {\n      distinguishedName: {\n        commonName: '\u003ca name your customers would recognize\u003e',\n        emailAddress: '\u003cyour@email.address\u003e',\n        country: '\u003ctwo-letter ISO country code\u003e',\n        stateOrProvince: '\u003cstate or province\u003e',\n        locality: '\u003ccity\u003e',\n        organizationName: '\u003cname of your company or organization\u003e',\n        organizationalUnitName: '\u003cname of your department within the origanization\u003e',\n      }\n    });\n    ```\n2. Deploy the stack:\n    ```console\n    $ cdk deploy $stack_name\n    ...\n    Outputs:\n    $stack_name.CodeSigningCertificateXXXXXX = -----BEGIN CERTIFICATE REQUEST-----\n    ...\n    -----END CERTIFICATE REQUEST-----\n    ```\n3. Forward the Certificate Signing Request (the value of the stack output that\n   starts with `-----BEGIN CERTIFICATE REQUEST-----` and ends with\n   `-----END CERTIFICATE REQUEST-----`) to a Certificate Authority, so they can\n   provde you with a signed certificate.\n4. Update your stack with the signed certificate obtained from the CA. The below\n   example assumes you palced the PEM-encoded certificate in a file named\n   `certificate.pem` that is in the same folder as file that uses the code:\n    ```ts\n    // Import utilities at top of file:\n    import fs = require('fs');\n    import path = require('path');\n    // ...\n    new delivlib.CodeSigningCertificate(stack, 'CodeSigningCertificate', {\n      distinguishedName: {\n        commonName: '\u003ca name your customers would recognize\u003e',\n        emailAddress: '\u003cyour@email.address\u003e',\n        country: '\u003ctwo-letter ISO country code\u003e',\n        stateOrProvince: '\u003cstate or province\u003e',\n        locality: '\u003ccity\u003e',\n        organizationName: '\u003cname of your company or organization\u003e',\n        organizationalUnitName: '\u003cname of your department within the origanization\u003e',\n      },\n      // Addin the signed certificate\n      pemCertificate: fs.readFileSync(path.join(__dirname, 'certificate.pem'))\n    });\n    ```\n5. Redeploy your stack, so the self-signed certificate is replaced with the one\n   received from your CA:\n    ```console\n    $ cdk deploy $stackName\n    ```\n\n### Maven Central (Java)\n\nThis publisher can publish Java packages to [Maven\nCentral](https://search.maven.org/).\n\nThis publisher expects to find a local maven repository under the `java/`\ndirectory in your build output artifacts. You can create one using the\n`altDeploymentRepository` option for `mvn deploy` (this assumes `dist` if the\nroot of your artifacts tree):\n\n```console\n$ mvn deploy -D altDeploymentRepository=local::default::file://${PWD}/dist/java\n```\n\nUse `pipeline.publishToMaven` to add this publisher to your pipeline:\n\n```ts\npipeline.publishToMaven({\n  mavenLoginSecret: { secretArn: 'my-maven-credentials-secret-arn' },\n  signingKey: mavenSigningKey,\n  stagingProfileId: '11a33451234521'\n});\n```\n\nIn order to configure the Maven publisher, you will need at least three pieces\nof information:\n\n1. __Maven Central credentials__ (`mavenLoginSecret`) stored in AWS Secrets Manager\n2. __GPG signing key__ (`signingKey`) to sign your Maven packages\n3. __Staging profile ID__ (`stagingProfileId`) assigned to your account in Maven Central.\n\nThe following sections will describe how to obtain this information.\n\n#### GPG Signing Key\n\nSince Maven Central requires that you sign your packages you will need to\ncreate a GPG key pair and publish it's public key to a well-known server:\n\nThis library includes a GPG key construct:\n\n```ts\nconst mavenSigningKey = new delivlib.OpenPGPKeyPair(this, 'MavenCodeSign', {\n  email: 'your-email@domain.com',\n  identity: 'your-identity',\n  secretName: 'maven-code-sign',\n  pubKeyParameterName: 'mavenPublicKey',\n  keySizeBits: 4096,\n  expiry: '1y',\n  version: 1.0\n});\n```\n\nAfter you've deployed your stack once, you can go to the SSM Parameter Store\nconsole and copy the public key from the new parameter created by your stack\nunder the specified secret name. Then, you should paste this key to any of the\nsupported key servers (recommended: https://keyserver.ubuntu.com).\n\n#### Sonatype Credentials\n\nIn order to publish to Maven Central, you'll need to follow the instructions in\nMaven Central's [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html)\nand create a Sonatype account and project via JIRA:\n\n1. [Create JIRA\n   account](https://issues.sonatype.org/secure/Signup!default.jspa)\n2. [Create new project\n   ticket](https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21\u0026pid=10134)\n3. Once you have the user name and password of your Sonatype account, create an\n   AWS Secrets Manager secret with a `username` and `password` key/value fields\n   that correspond to your account's credentials.\n\n#### Staging Profile ID\n\nAfter you've obtained a Sonatype account and Maven Central project:\n\n1. Log into https://oss.sonatype.org\n2. Select \"Staging Profiles\" from the side bar (under \"Build Promotion\")\n3. Click on the \"Releases\" staging profile that you registered\n4. The URL of the page should change and include your profile ID. For example: `https://oss.sonatype.org/#stagingProfiles;11a33451234521`\n\nThis is the value you should assign to the `stagingProfileId` option.\n\n### PyPI (Python)\n\nThis publisher can publish modules to [PyPI](https://pypi.org/).\n\nThis publisher will publish all files under the `python/` directory in your\nbuild output artifacts to PyPI using the following command:\n\n```sh\ntwine upload --skip-existing python/**\n```\n\nTo use this publisher, you will need to an\n[account](https://pypi.org/account/register/) with PyPI. Then store your\ncredentials in an AWS Secrets Manager secret, under the `username` and\n`password` fields.\n\nNow, use `pipeline.publishToPyPi` to add this publisher to your pipeline:\n\n```ts\npipeline.publishToPyPi({\n  loginSecret: { secretArn: 'my-pypi-credentials-secret-arn' }\n});\n```\n\n### GitHub Releases\n\nThis publisher can package all your build artifacts, sign them and publish them\nto the \"Releases\" section of a GitHub project.\n\nThis publisher relies on two files to produce the release:\n\n- `build.json` a manifest that contains metadata about the release.\n- `CHANGELOG.md` (optional) the changelog of your project, from which the\n  release notes are extracted. If not provided, no release notes are added\n  to the release.\n\n\u003ca id=\"manifest\"/\u003e\n\nThe file `build.json` is read from the root of your artifact tree. It should\ninclude the following fields:\n\n```json\n{\n  \"name\": \"\u003cproject name\u003e\",\n  \"version\": \"\u003cproject version\u003e\",\n  \"commit\": \"\u003csha of commit\u003e\"\n}\n```\n\nThis publisher does the following:\n\n1. Create a zip archive that contains the entire build artifacts tree under the\n   name `${name}-${version}.zip`.\n2. Sign the archive using a GPG key and store it under\n   `${name}-${version}.zip.sig`\n3. Check if there is already a git tag with `v${version}` in the GitHub\n   repository. If there is, bail out successfully.\n4. If there's a `CHANGELOG.md` file, and extract the release notes for\n   `${version}` (uses [changelog-parser](https://www.npmjs.com/package/changelog-parser))\n5. Create a GitHub release named `v${version}`, tag the specified `${commit}`\n   with the release notes from the changelog.\n6. Attach the zip archive and signature to the release.\n\nTo add a GitHub release publisher to your pipeline, use the\n`pipeline.publishToGitHub` method:\n\n```ts\npipeline.publishToGitHub({\n  githubRepo: targetRepository,\n  signingKey: releaseSigningKey\n});\n```\n\nThe publisher requires the following information:\n\n- The target GitHub project (`githubRepo`): see [instructions](#github) on how to connect\n  to a GitHub repository. It doesn't have to be the same repository as the source repository,\n  but it can be.\n- A GPG signing key (`signingKey`): a `delivlib.SigningKey` object used to sign the\n  zip bundle. Make sure to publish the public key to a well-known server so your users\n  can validate the authenticity of your release (see [GPG Signing Key](#gpg-signing-key) for\n  details on how to create a signing key pair and extract it's public key). You can either use\n\n### GitHub Pages\n\nThis publisher allows you to publish versioned static web-site content to GitHub Pages.\n\nThe publisher commits the entire contents of the `docs/` directory into the root of the specified\nGitHub repository, and also under the `${version}/` directory of the repo (which allows users\nto access old versions of the docs if they wish).\n\nNOTE: static website content can grow big. Therefore, this publisher will always force-push\nto the branch without history (history is preserved via the `versions/` directory). Make sure\nyou don't protect this branch against force-pushing or otherwise the publisher will fail.\n\nThis publisher depends on the following artifacts:\n\n1. `build.json`: build manifest (see [schema](#manifest) above)\n2. `docs/**`: the static website contents\n\nThis is how this publisher works:\n\n1. Read the `version` field from `build.json`\n2. Clone the `gh-pages` branch of the target repository to a local working directory\n3. Rsync the contents of `docs/**` both to `versions/${version}` and to `/` of the working copy.\n5. Commit and push to the `gh-pages` branch on GitHub\n\n\u003e NOTE: if `docs/` contains a fully rendered static website, you should also include\n\u003e a `.nojekyll` file to [bypass](https://blog.github.com/2009-12-29-bypassing-jekyll-on-github-pages/)\n\u003e Jekyll rendering.\n\nTo add this publisher to your pipeline, use the `pipeline.publishToGitHubPages` method:\n\n```ts\npipeline.publishToGitHubPages({\n  githubRepo,\n  sshKeySecret: { secretArn: 'github-ssh-key-secret-arn' },\n  commitEmail: 'foo@bar.com',\n  commitUsername: 'foobar',\n  branch: 'gh-pages' // default\n});\n```\n\nIn order to publish to GitHub Pages, you will need the following pieces of information:\n\n1. The target GitHub repository (`githubRepo`). See [instructions](#github) on\n   how to connect to a GitHub repository. It doesn't have to be the same\n   repository as the source repository, but it can be.\n2. SSH private key (`sshKeySecret`) for pushing to that repository stored in AWS\n   Secrets Manager which is configured in your GitHub repository as a deploy key\n   with write permissions.\n3. Committer email (`commitEmail`) and username (`commitUsername`).\n\nTo create an ssh deploy key for your repository:\n\n1. Follow [this\n   guide](https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys)\n   to produce a private/public key pair on your machine.\n1. Add the deploy key to your repository with write permissions.\n1. Create an AWS Secrets Manager secret and paste the private key as plaintext\n   (not key/value).\n1. Use the name of the AWS Secrets Manager secret in the `sshKeySecret` option.\n\n## Metrics\n\nThe `Pipeline` construct automatically creates the following metrics in CloudWatch\nfor the configured pipelines. These are published under the namespace 'CDK/Delivlib'.\n\n- Execution Failures: The number of failures of the pipeline execution.\n  When a pipeline execution fails, a '1' is recorded and forevery success, a '0' is\n  recorded.\n\n  Metric Name: *Failures*\n  Dimensions:\n  - *Pipeline*: The pipeline name in CodePipeline.\n\n- Action Failures: The number of failures per action per pipeline. An execution\n  failure can be due to multiple actions failing.\n  For every action failure, a '1' is recorded and for every success, a '0' is recorded.\n\n  Metric Name: *Failures*\n  Dimensions:\n  - *Pipeline*: The pipeline name in CodePipeline.\n  - *Action*: THe name of the action that succeeded or failed.\n\n## Automatic Bumps and Pull Request Builds\n\n### GitHub Access\n\nIf your source repository is GitHub, in order to enable these features you will\nneed to manually connect AWS CodeBuild to your GitHub account. Otherwise, you\nwill receive the following error message:\n\n```\nNo Access token found, please visit AWS CodeBuild console to connect to GitHub\n(Service: AWSCodeBuild; Status Code: 400; Error Code: InvalidInputException;\nRequest ID: ab458603-6fd4-11e8-9310-ff116e0423f9)\n```\n\nTo connect, go to the AWS CodeBuild console, click \"Create Project\", select a\nGitHub source and hit \"Connect\". There is no need to save the new project. This\nneeds to be done once per account/region.\n\n### Automatic Bumps\n\nA bump is the process of incrementing the version number of the project. When\nthe version number is incremented and a commit is pushed to the master branch,\nthe publishing actions will release the new version to all repositories.\n\nThis feature enables achieving full continuous delivery for libraries.\n\nTo enable automatic bumps, you will first need to determine how to perform a\nbump in your repository. What command should be executed in order to increment\nthe version number, update change log, etc.\n\nThe bump command is expected to perform the bump and issue a **commit** and a\n**tag** to the local repository with the version number.\n\nFor JavaScript projects, the\n[standard-version](https://github.com/conventional-changelog/standard-version)\ntool will do exactly that, so it is the recommended mechanism for such projects.\n\nOnce a bump is committed, the commit will be pushed either to a dedicated branch\ncalled `bumps/VERSION` or to a branch of your choosing such as `master`.\n\nTo set up bumps, simply call `autoBump` on your pipeline. The following example\nsets up a bump on the default schedule (12pm UTC daily) which will automatically\npush the to \"master\" (which will trigger a release).\n\n```ts\nconst bump = pipeline.autoBump({\n  bumpCommand: 'npm i \u0026\u0026 npm run bump',\n  branch: 'master'\n});\n```\n\nYou can customize the environment used for running the bump script.\n\nIf a bump fails, the `bump.alarm` CloudWatch alarm will be triggered.\n\nNOTE: there is currently no way for the bump command to indicate to the\nsystem that a bump is not needed (i.e. no changes have been made to the\nlibrary).\n\n## Failure Notifications\n\nPipelines can be configured with notifications that will be sent on any failure in pipeline's stages. Notifications can\nbe sent to either a Slack channel or a Chime room. The following code configures one of each -\n\n```ts\n// Slack\nconst teamChannel = new chatbot.SlackChannelConfiguration(this, {\n  // ...\n});\npipeline.notifyOnFailure(PipelineNotification.slack({\n  channels: [teamChannel]\n}));\n\n// Chime\nconst teamRoomWebhook = 'https://hooks.chime.aws/incomingwebhooks/1c3588c7-623d-4799-af9b-8b1818fca779?token=cUMzOVA4OXl8MXxCaHJlZ0RUVm03TmZVMkpoTzlwa3NVbXJCam8tNWF3UGdzemVqZndsZERV';\npipeline.notifyOnFailure(PipelineNotification.chime({\n  webhookUrl: [ teamRoomWebhook ]\n}));\n```\n\n## ECR Mirror\n\nBuilds commonly use Docker images from DockerHub as their base image. In fact, delivlib defaults its build\nimage to `jsii/superchain`. However, DockerHub has throttles in place for the volume of unauthenticated and\nauthenticated pulls. This can cause CodeBuild jobs that run frequently to fail from DockerHub's throttling.\n\nThe `EcrMirror` construct can be used to synchronize, on a specific schedule, Docker images between DockerHub and\na local ECR registry in the AWS account.\n\n```ts\nnew EcrMirror(this, 'RegistrySync', {\n  sources: [\n    MirrorSource.fromDockerHub('jsii/superchain:1-bullseye-slim'),\n    MirrorSource.fromDockerHub('python:3.6'),\n  ],\n  dockerhubCredentials: // ...\n  schedule: events.Schedule.cron( ... ),\n})\n```\n\nYou can also use the `MirrorSource.fromDirectory()` API if you would like to build a new Docker image based on a\nDockerfile. The Dockerfile should be placed at the top level of the specified directory.\n\nIn addition to this, an `EcrMirrorAspect` is available that can walk the construct tree and replace all occurrences\nof Docker images in CodeBuild projects with ECR equivalents if they are found in the provided `EcrMirror` construct.\nThis can be applied to an entire stack as so -\n\n```ts\nconst stack = new MyStack(...);\n// ...\nAspects.of(stack).add(new EcrMirrorAspect(ecrMirrorStack.mirror));\n```\n\n## Package Integrity\n\nTo ensure the artifacts published into package managers exactly correspond to your source code, delivlib offers a `PackageIntegrityValidation` construct.\nIt will perform periodic integrity checks, comparing the published artifact against an artifact directly build from source code.\n\nThis can help detect scenarios where your publishing platform may have been compromised, and your packages no longer contain the expected bits.\n\n```ts\n// first import the secret containing your github token secret.\n// the secret value should be the token in plain text.\nconst token = sm.Secret.fromSecretCompleteArn(stack, 'GitHubSecret', '\u003csercet-arn\u003e');\n\n// validate integrity of your package, hosted in a github repository.\nnew PackageIntegrityValidation(stack, 'PackageValidation', {\n  repository: '\u003crepository-slug\u003e',\n  buildImage: codebuild.LinuxBuildImage.fromDockerRegistry('\u003cdocker-image\u003e'),\n  githubTokenSecret: token,\n});\n```\n\nAt a high level, the validation is performed like so:\n\n1. Clone the GitHub repository and checkout to the latest tag.\n2. Build the repository to produce local artifacts from the source code.\n3. Download the corresponding artifacts from package managers.\n4. Compare.\n\nBy default the validation will run once a day, but you can configure its schedule using the `schedule` option.\nIf the validation fails, a CloudWatch alarm will be triggered, which is accessible via the `failureAlarm` property.\n\n## Contributing\n\nSee the [contribution guide](./CONTRIBUTING.md) for details on how to submit\nissues, pull requests, setup a development environment and publish new releases\nof this library.\n\n## License\n\nThis library is licensed under the Apache 2.0 License.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdklabs%2Faws-delivlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcdklabs%2Faws-delivlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdklabs%2Faws-delivlib/lists"}