How to Become A Programming Polyglot by One-language Effort

Scott Hsieh (史考特)
10 min readMay 17, 2021

--

Build an AWS CDK Construct Library Project by projen

1. Introduction
2. Preparation
2.1 Initialize a projen project
2.2 Figure out each projen command and arguments in AwsCdkConstructLibrary
2.3 Build a construct library
3. Publishing to supported language repositories
3.1 How to publish a package in npm?
- Arguments in the .projenrc.js you need to give attention to
- Required information by Github Actions
3.2 How to publish a package to PyPi?
- Arguments in .projenrc.js you need to give attention to
- Required information by Github Actions
3.3 How to publish a package to Maven?
- Arguments in the .projenrc.js you need to give attention to
- Few more steps for Maven
- Required information by Github Actions
3.4 How to publish a package to Nuget?
- Arguments in the .projenrc.js you need to give attention to
- required information by Github Actions
4. Conclusion

example Github repo: https://github.com/HsiehShuJeng/projen-simple

Required Secrets by Github Actions in order to Publish Construct Library in Maven, PyPI, npm, and NuGet

Introduction

projen is a tool for developers to manage their project configurations via code. It currently supports, well, by the time I was writing this blog post, 15 genres of projects. The one I felt the most interested in is building AWS CDK construct libraries for popular programming languages. Behind the scene that you can generate out a construct library for the languages such as C#, Go, Java, Python, and Typescript through a single project managed by projen is due to the power of jsii.

Simply put, you could regard jsii a technology that enables the AWS CDK to deliver polyglot libraries from a singe codebase. More simply, you could attempt to remember that by the jsii technology, you are empowered to write a library with one programming language such as Typescript and output the corresponding libraries in .NET, Go, Java, and Python.

I’ve been writing the AWS CDK using Typescript for few months. I chose it because it’s the origin. Don’t you ever hear the voice in your heart: ‘It’s time to back to the Motherland’? And the Tomorrowland is awesome, too. You agree?

Aight, back to the track. The AWS CDK has been assisting me in personal and company projects. Just way better than JSON and YAML. I have strong confidence I’ll be loyal to the CDK for sure instead of composing a CloudFormation template using yaml if there is no necessity.

Few weeks ago, I was invited by an AWS Developer Advocate to participate in a project called cdk-cloudfront-plus, and the project is managed by projen. Truly impressed with the tool. And finally I got some time the last weekend to dig into the tool, projen, a little bit.

Preparation

During the survey, I found out a Github repo maintained by Sebastian Hesse is especially helpful though the part for Java (Maven) has been kinda outdated. My goal is to output a library with the all supported programming languages in jsii. My familiarity to those languages is Python, Java, Typescript, Go, and C#. Since I still haven’t grasped the mechanism between Javascript and Go via jsii and GOPATH, i.e., haven’t figured out what naming and settings in the projen project can make the CI of Github Actions work therefore the Go package of the construct library. Considering time, I would just share the core part of how to output packages in 4 programming languages at the same time.

Initialize a projen project

$ npx projen new awscdk-construct
$ alias pj='npx projen' // I moved it into ~/.bash_profile on my M1.

Figure out each projen command and arguments in AwsCdkConstructLibrary

Though Sebastian said it probably takes you around 30 minutes to get along with projen, I actually spent few hours to make projen my friend. And publishing to Central Maven occupies most of the time. Hope the following content might save some time for you on the way to become a programming polyglot.

Build a construct library

I searched articles in the AWS Blog with the first key appeared in my mind at the moment. And got this: ‘Introducing Amazon API Gateway service integration for AWS Step Functions’. I CDK-ified the first example combined with a state machine and an API Gateway Rest API and published it to 4 language repositories with pojen.

State Machine Diagram Generated by CDK Example

Publishing to supported language repositories

How to publish a package in npm?

Arguments in the .projenrc.js you need to give attention to

  • releaseBranches: branches which trigger a release.
  • releaseToNpm : automatically release to npm when new versions are introduced.
  • releaseWorkflow: define a GitHub workflow for releasing from “main” when new versions are bumped.
  • releaseEveryCommit: automatically release new versions every commit to one of branches in releaseBranches.
new AwsCdkConstructLibrary({
.
.
.
releaseToNpm: true,
releaseBranches: ['main'],
releaseWorkflow: true,
releaseEveryCommit: true
.
.
.
})

Required information by Github Actions

  • NPM_TOKEN: it is required by Github Actions to publish the npm package.

After executing npx projen (you could consider making it as an alias such as pj), you’ll notice in the release.yml under .github/workflows
that NPM_TOKEN is required by Github Actions to publish the npm package. If you’re just an npm newbie as me, don’t panic! Be strong, be calm. The following steps are what you need to go through:

  1. create an npm account (email validation is required)
  2. create an access token on the web page of your npm account. Choose the type of AUTOMATION when you’re about to create the access token. AUTOMATION! AUTOMATION! AUTOMATION TYPE! It’s important to be emphasized three times.
  3. store the access token as an Actions secret in your Github repository.

If you go everything smoothly, you get an email whose content will be similar to the following picture. And you can find out published npm packages at the npm pool as here.

Email Message after Publishing an npm package via projen with success

How to publish a package to PyPi?

Arguments in .projenrc.js you need to give attention to

  • publishToPypi

You gotta set a distribution name and a module name for the Python package.

publishToPypi: {    
distName: 'scotthsieh_projen_statemachine',
module: 'scotthsieh_projen_statemachine'
}

Required information by Github Actions

  • TWINE_USERNAME
  • TWINE_PASSWORD

If you read the content related to publishing an npm package above, you’ll be very clear that those environment variables are required by what service. With proper settings in the .projenrc.js , you’ll find an entry release_pypi in the release.yml under .github/workflows.

TWINE_USERNAME and TWINE_PASSWORD is your PyPi account information. And your PyPi account needs to be verified.

With a green check symbol given by Github Actions, you can see your package (project) in your PyPI account which means you could find out the Python package by the name you’ve declared in the projen project in the PyPI pool.

Python Package in Your PyPI Account after a Successful CICD by Github Actions.

How to publish a package to Maven?

Arguments in the .projenrc.js you need to give attention to

  • publishToMaven

You need to declare groupId, artifactId, and package as you always do in managing a Java application project by Maven except version information in this construct library project based on projen. The default Maven endpoint in the .projenrc.js is https://oss.sonatype.org. Due to the policy executed by Sonatype, you need to tweak it as https://s01.oss.sonatype.org in the .projenrc.js for those who create their Sonatype JIRA accounts after February, 2021.

publishToMaven: {
mavenGroupId: 'io.github.hsiehshujeng',
mavenArtifactId: 'projen-inception',
javaPackage: 'io.github.hsiehshujeng.projen.inception',
mavenEndpoint: 'https://s01.oss.sonatype.org' // check https://central.sonatype.org/publish/release/#login-into-ossrh
},

Few more steps for Maven

  1. Create an account for Maven central
    You need to create an account for Maven central via OSSRH. Two short films in the guide will be helpful. You could choose a domain as groupId e.g. org.example, for the account, or your Github name as groupId , e.g. io.github.${GITHUB_USERNAME}. (com.github has no long been supported as a valid groupId since Apr. 1st, 2021 and the detail can be looked up here)
    After you create a JIRA issue in the Sonatype JIRA tracking system, you’ll get response within sometime. Take me for example, it’s only a 4-minute waiting after I created the JIRA issue. You only need to respond accordingly from their robotic response.
    Within this exploration for projen, my account for Maven is connected to the JIRA issue OSSRH-68981.
  2. Create a GPG key
    How to generate the GPG key for my projen project to produce the Java library? You could refer to ‘How to create a GPG key?’ at the section of Maven in jsii-release. During the generating progress of the GPG key, you will be asked to enter a passphrase for the key. Please memorize the passphrase of the GPG key in any way like it’s your lifetime partner, promise me, since you’ll need it for an Actions secret and exporting the private key.
    Some information you might find it useful.
    • consider executing $ gpg --full-generate-key and choose RSA with the length of 4,096.
    • you’ll need to paste the public key onto https://keyserver.ubuntu.com/.

After executing npx projen (you could consider making it as an alias such as pj), you should find the entry named release_maven in the release.yml under .github/workflows.

Required information by Github Actions

  • MAVEN_GPG_PRIVATE_KEY: execute the following command then past the one-line content to this Actions secret.
echo $(cat -e private.pem) | sed 's/\$ /\\n/g' | sed 's/\$$//'
  • MAVEN_GPG_PRIVATE_KEY_PASSPHRASE: the passphrase you entered during the generating progress of the GPG key.
  • MAVEN_USERNAME: the user name you take to log-in the Sonatype JIRA tracking system.
  • MAVEN_PASSWORD: the password you take to log-in the Sonatype JIRA tracking system.
  • MAVEN_STAGING_PROFILE_ID, an identity shown up on the URL of Staging Profile after logging in https://s01.oss.sonatype.org/.

If you go smoothly, you should be able to find the Java package similar to this.

Java Package Searched with io.github.hsiehshujeng after a Successful CICD by Github Actions.

When the tunnel to the Central Maven is open after you upload an artifact into the Nexus Repository Manager with success, you should be able to search your published Java package at https://search.maven.org.

Search Result at Maven Central Repository Search

How to publish a package to Nuget?

Arguments in the .projenrc.js you need to give attention to

  • publishToNuget

Just follow the naming rules of NuGet packages.

publishToNuget: {
dotNetNamespace: 'ScottHsieh.Examples',
packageId: 'Projen.Inception',
},

By executing npx projen with proper command (you could consider making it as an alias such as pj), you are able to get the entry named release_nuget in the release.yml under .github/workflows.

Required information by Github Actions

  • NUGET_API_KEY: a token that enables your project to deploy a NuGet package

With a while after the CI in Github Actions is over, you should get an email similar to the following picture and can search your NuGet package as here in the NuGet Gallery.

Received Email Message after Publishing a NuGet package via projen with success

How to publish a package to Go? ( Incomplete)

Arguments in the .projenrc.js you need to give attention to

  • publsihToGo

required information by Github Actions

  • NUGET_API_KEY: a token that enables your project to deploy a nuget package

Conclusion

If all things go done well, you should see the following diagram in your Github repository.

Packages Output to Supported Language Repositories with Success

By confirming the custom AWS construct has been published to the corresponding language pools, you could start deploying a stack with the construct with a programming language you prefer.

  • how to deploy with Typescript: refer to here
  • how to deploy with Python: refer to here
  • how to deploy with Java: refer to here
  • how to deploy with Csharp: refer to here
A Glimpse of Successful Deployments via Different Programming Languages

If you wanna see the reality of this post by accident, please go to this repo maintained by me. May the code be with you. See you next time. ^.<

References

  1. Ben-Israel, E., 2021. PROJECT STRUCTURE. [online] Cdkworkshop.com. Available at: <https://cdkworkshop.com/40-dotnet/20-create-project/300-structure.html> [Accessed 18 May 2021].
  2. Bui-Palsulich, T., 2019. Publishing Go Modules — The Go Blog. [online] Blog.golang.org. Available at: <https://blog.golang.org/publishing-go-modules> [Accessed 15 May 2021].
  3. Central.sonatype.org. 2021. Central Repository Changelog — The Central Repository Documentation. [online] Available at: <https://central.sonatype.org/changelog/#2021-04-01-comgithub-is-not-supported-anymore-as-a-valid-coordinate> [Accessed 15 May 2021].
  4. Central.sonatype.org. 2021. OSSRH Guide — The Central Repository Documentation. [online] Available at: <https://central.sonatype.org/publish/publish-guide/#deployment> [Accessed 15 May 2021].
  5. Docs.github.com. 2021. Encrypted secrets — GitHub Docs. [online] Available at: <https://docs.github.com/en/actions/reference/encrypted-secrets> [Accessed 15 May 2021].
  6. Docs.npmjs.com. 2021. About access tokens | npm Docs. [online] Available at: <https://docs.npmjs.com/about-access-tokens> [Accessed 15 May 2021].
  7. Hesse, S., 2021. Migrating a CDK Construct to projen and jsii . [online] Sebastian Hesse — Software Engineer. Available at: <https://www.sebastianhesse.de/2021/03/01/migrating-a-cdk-construct-to-projen-and-jsii/> [Accessed 15 May 2021].
  8. Jones, M., 2019. Scoped API keys. [online] Docs.microsoft.com. Available at: <https://docs.microsoft.com/en-us/nuget/nuget-org/scoped-api-keys> [Accessed 16 May 2021].
  9. Sonatype, Inc., 2021. OSSRH Guide — The Central Repository Documentation. [online] Central.sonatype.org. Available at: <https://central.sonatype.org/publish/publish-guide/> [Accessed 15 May 2021].
  10. The Apache Software Foundation, 2021. Maven — Guide to uploading artifacts to the Central Repository. [online] Maven.apache.org. Available at: <https://maven.apache.org/repository/guide-central-repository-upload.html> [Accessed 15 May 2021].
  11. seeebiii, 2021. Create and Publish CDK Constructs Using projen and jsii. [online] GitHub. Available at: <https://github.com/seeebiii/projen-test> [Accessed 15 May 2021].

--

--

Scott Hsieh (史考特)
Scott Hsieh (史考特)

Written by Scott Hsieh (史考特)

10 x AWS-certified, Data Architect in the 104 Corporation. An AWS Data Hero

No responses yet