Skip to content

Commit a64f31b

Browse files
committed
feat: initial commit
0 parents  commit a64f31b

32 files changed

+8263
-0
lines changed

.envrc.example

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export AWS_REGION=... # AWS region to use, e.g. eu-west-1
2+
export AWS_DEFAULT_REGION=$AWS_REGION
3+
export AWS_ACCESS_KEY_ID= ... # Your AWS Access Key ID
4+
export AWS_SECRET_ACCESS_KEY=... # Your AWS Secret Access Key
5+
# silence warnings because of using a newer Node.js version
6+
export JSII_SILENCE_WARNING_UNTESTED_NODE_VERSION=1
7+
export NODE_NO_WARNINGS=1

.github/CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @coderbyheart @pudkrong

.github/workflows/deploy.yaml

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Deploy
2+
3+
permissions:
4+
id-token: write
5+
6+
on:
7+
workflow_dispatch:
8+
push:
9+
branches:
10+
- saga
11+
env:
12+
CI: 1
13+
FORCE_COLOR: 3
14+
JSII_SILENCE_WARNING_UNTESTED_NODE_VERSION: 1
15+
NODE_NO_WARNINGS: 1
16+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17+
18+
jobs:
19+
deploy:
20+
runs-on: ubuntu-22.04
21+
22+
environment: ci
23+
24+
timeout-minutes: 5
25+
26+
steps:
27+
- uses: actions/checkout@v4
28+
29+
- uses: actions/setup-node@v4
30+
with:
31+
node-version: "20.x"
32+
cache: "npm"
33+
34+
- name: Install dependencies
35+
run: npm ci --no-audit
36+
37+
- name: Configure AWS credentials
38+
uses: aws-actions/configure-aws-credentials@v4
39+
with:
40+
# The role is set up via https://github.com/hello-nrfcloud/ci
41+
role-to-assume: |
42+
arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID_CI }}:role/hello-nrfcloud-ci-${{ github.event.repository.name }}
43+
aws-region: ${{ vars.AWS_REGION_CI }}
44+
45+
- run: npx cdk deploy
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Test and Release
2+
3+
permissions:
4+
contents: write
5+
issues: write
6+
7+
on:
8+
push:
9+
10+
env:
11+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- uses: actions/setup-node@v4
21+
with:
22+
node-version: "20.x"
23+
cache: "npm"
24+
25+
- name: Install dependencies
26+
run: npm ci --no-audit
27+
28+
- name: Compile TypeScript
29+
run: npx tsc
30+
31+
- name: Check source code with eslint
32+
run: npx eslint ./
33+
34+
- name: Check if source code is properly formatted
35+
run: npx prettier -c ./
36+
37+
- name: Semantic release
38+
run: npx semantic-release
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Sync repository info from package.json
2+
3+
env:
4+
GITHUB_TOKEN: ${{ secrets.UPDATE_REPO_INFO_PAT }}
5+
6+
on:
7+
push:
8+
branches:
9+
- saga
10+
paths:
11+
- "package.json"
12+
- ".github/workflows/update-repo-info.yaml"
13+
workflow_dispatch:
14+
15+
jobs:
16+
update_repo_info:
17+
runs-on: ubuntu-22.04
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Sync repository description
23+
run:
24+
gh repo edit --description "`cat package.json | jq -r '.description'`"
25+
26+
- name: Sync repository topics
27+
run:
28+
cat package.json | jq '.keywords[]' | xargs -I'{}' gh repo edit
29+
--add-topic {}
30+
31+
- name: Sync homepage
32+
run: gh repo edit --homepage "`cat package.json | jq -r '.homepage'`"

.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# This file should only cover artifacts caused by the source code in this
2+
# repository, not those caused by the personal choice of editor and/or
3+
# environment of a developer.
4+
# See adr/002-clean-gitignore.md
5+
node_modules/
6+
npm-debug.log
7+
.swc/
8+
cdk.out/
9+
dist/
10+
.envrc
11+
/certificates/
12+
cdk.context.json
13+
e2e-test-result.json

.husky/commit-msg

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx commitlint --edit $1

.husky/pre-commit

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
npx lint-staged
2+
npx tsc

.prettierignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist/
2+
package-lock.json

CODE_OF_CONDUCT.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See <https://github.com/bifravst/.github/blob/saga/CODE_OF_CONDUCT.md>

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See <https://github.com/bifravst/.github/blob/saga/CONTRIBUTING.md>

LICENSE

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2023-2024, Nordic Semiconductor ASA | nordicsemi.no
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# `hello.nrfcloud.com` CI
2+
3+
[![GitHub Actions](https://github.com/hello-nrfcloud/backend/workflows/Test%20and%20Release/badge.svg)](https://github.com/hello-nrfcloud/backend/actions/workflows/test-and-release.yaml)
4+
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
5+
[![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com)
6+
[![@commitlint/config-conventional](https://img.shields.io/badge/%40commitlint-config--conventional-brightgreen)](https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-conventional)
7+
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier/)
8+
[![ESLint: TypeScript](https://img.shields.io/badge/ESLint-TypeScript-blue.svg)](https://github.com/typescript-eslint/typescript-eslint)
9+
10+
Sets up the permissions in our AWS CI account for the repositories in this
11+
GitHub organization that are supposed to have access so they are be able to use
12+
it for CI runs.
13+
14+
The allowed list of repositories is managed via the
15+
[`ci` team](https://github.com/orgs/hello-nrfcloud/teams/ci/repositories).
16+
17+
> [!CAUTION]
18+
> Do not run this against the production account, but against the CI account.
19+
20+
```bash
21+
npx cdk deploy
22+
```
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# ADR 001: Use saga as the name for the main branch
2+
3+
Historically, Git and other software use terms such as `master/slave`,
4+
`whitelist/blacklist`, which are based on racial concepts. Their continued use
5+
maintains the racial stereotypes they depict. Better alternatives in meaning and
6+
technical correctness exist, like `leader/follower`, `blocklist/allowlist`.
7+
8+
In the Nordic mythology, a `saga` is a long, continuous recollection of stories
9+
about the history of humans, legends, and Gods. The term `saga` reflects very
10+
well what happens in a Git repository. Changes happen in branches (some teams
11+
tie them to _User Stories_, which are sometimes directly or loosely coupled to
12+
the main branch). Once the changes are finalized, they get added to the main
13+
branch, or get appended in the case of a rebase. The mental model of a big book
14+
of stories fits this process very well.
15+
16+
Therefore, the main branch in this project is named `saga`. `master` must not be
17+
used.

adr/002-clean-gitignore.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# ADR 002: Clean `.gitignore` file
2+
3+
A `.gitignore` file in a project must only cover the artifacts caused by the
4+
contained source code and not those caused by the personal choice of editor or
5+
the environment of a developer.
6+
7+
This is explained in detail
8+
[here](https://github.com/coderbyheart/first-principles/issues/30).

adr/003-use-of-typescript.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# ADR 003: use of TypeScript
2+
3+
This project is developed using [TypeScript](https://www.typescriptlang.org/) (a
4+
typed superset of JavaScript).
5+
6+
JavaScript is the most popular language according to the
7+
[2019 Stack Overflow survey](https://insights.stackoverflow.com/survey/2019#technology)
8+
and it is therefore likely that many developers using the project will be
9+
familiar with the language concepts and how to use and run it.
10+
11+
Virtually all cloud providers provide their SDKs in JavaScript or TypeScript
12+
which this project can integrate natively.

adr/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Architecture decision records
2+
3+
This folder contains the architecture decision records (ADRs) for this project.
4+
5+
To know more about ADRs, see
6+
[Documenting architecture decisions](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
7+
and the video on
8+
[Communicating and documenting architectural decisions](https://www.youtube.com/watch?v=rwfXkSjFhzc).

cdk.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"app": "npx tsx --no-warnings cdk/ci.ts"
3+
}

cdk/CIApp.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { App } from 'aws-cdk-lib'
2+
import { CIStack } from './CIStack.js'
3+
4+
export class CIApp extends App {
5+
public constructor(
6+
name: string,
7+
args: ConstructorParameters<typeof CIStack>[2],
8+
) {
9+
super()
10+
11+
new CIStack(this, name, args)
12+
}
13+
}

cdk/CIStack.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { App, CfnOutput, Stack } from 'aws-cdk-lib'
2+
import { RepoPermission } from './RepoPermission.js'
3+
import type { Repos } from './listRepos.js'
4+
5+
export class CIStack extends Stack {
6+
public constructor(
7+
parent: App,
8+
name: string,
9+
{
10+
repos,
11+
gitHubOICDProviderArn,
12+
}: {
13+
gitHubOICDProviderArn: string
14+
repos: Repos
15+
},
16+
) {
17+
super(parent, name)
18+
19+
for (const { id, owner, name: repo } of repos) {
20+
const perm = new RepoPermission(this, repo, {
21+
repository: { id, owner, name: repo },
22+
gitHubOICDProviderArn,
23+
})
24+
25+
new CfnOutput(this, `${id}:ciRoleArn`, {
26+
exportName: `${name}:${id}:ciRoleArn`,
27+
description: `Role ARN to use for running continuous integration tests using GitHub Actions in the repository ${owner}/${repo} (${id})`,
28+
value: perm.role.roleArn,
29+
})
30+
}
31+
}
32+
}

cdk/RepoPermission.ts

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Duration, aws_iam as IAM, Stack } from 'aws-cdk-lib'
2+
import { Construct } from 'constructs'
3+
import type { Repository } from './listRepos.js'
4+
import { sanitize } from './sanitize.js'
5+
6+
export class RepoPermission extends Construct {
7+
public readonly role: IAM.IRole
8+
constructor(
9+
parent: Construct,
10+
id: string,
11+
{
12+
repository,
13+
gitHubOICDProviderArn,
14+
}: {
15+
repository: Repository
16+
gitHubOICDProviderArn: string
17+
},
18+
) {
19+
super(parent, id)
20+
21+
const gitHubOIDC = IAM.OpenIdConnectProvider.fromOpenIdConnectProviderArn(
22+
this,
23+
'gitHubOICDProvider',
24+
gitHubOICDProviderArn,
25+
)
26+
27+
this.role = new IAM.Role(this, 'ghRole', {
28+
roleName: `${Stack.of(this).stackName}-${sanitize(repository.name)}`,
29+
assumedBy: new IAM.WebIdentityPrincipal(
30+
gitHubOIDC.openIdConnectProviderArn,
31+
{
32+
StringEquals: {
33+
[`token.actions.githubusercontent.com:sub`]: `repo:${repository.owner}/${repository.name}:environment:ci`,
34+
[`token.actions.githubusercontent.com:aud`]: 'sts.amazonaws.com',
35+
},
36+
},
37+
),
38+
description: `This role is used by GitHub Actions to run Continuous Integration Tests ${
39+
Stack.of(this).stackName
40+
} in the repository ${repository.owner}/${repository.name} (${repository.id}).`,
41+
maxSessionDuration: Duration.hours(1),
42+
managedPolicies: [
43+
IAM.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
44+
],
45+
})
46+
}
47+
}

cdk/ci.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { IAMClient } from '@aws-sdk/client-iam'
2+
import { ensureGitHubOIDCProvider } from './ensureGitHubOIDCProvider.js'
3+
import { fromEnv } from '@nordicsemiconductor/from-env'
4+
import { CIApp } from './CIApp.js'
5+
import { listRepos } from './listRepos.js'
6+
7+
const { token } = fromEnv({
8+
token: 'GITHUB_TOKEN',
9+
})(process.env)
10+
11+
const repos = await listRepos(token, 'hello-nrfcloud', 'ci')
12+
for (const repo of repos) {
13+
console.debug(`Setting up permissions for ${repo.name} (${repo.id})...`)
14+
}
15+
16+
const iam = new IAMClient({})
17+
18+
new CIApp('hello-nrfcloud-ci', {
19+
gitHubOICDProviderArn: await ensureGitHubOIDCProvider({
20+
iam,
21+
}),
22+
repos,
23+
})

0 commit comments

Comments
 (0)