Skip to content

Commit

Permalink
feat(CI): add initial CI system
Browse files Browse the repository at this point in the history
  • Loading branch information
The0mikkel committed May 10, 2024
1 parent 8d0adc8 commit 1af6b1e
Show file tree
Hide file tree
Showing 7 changed files with 6,929 additions and 2 deletions.
106 changes: 106 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Docker build and push
on:
workflow_call:
inputs:
dockerfile:
description: 'Dockerfile path.'
required: false
default: './Dockerfile'
type: string
context:
description: 'Build context.'
required: false
default: '.'
type: string
arguments:
description: 'Build arguments. List of key-value pairs.'
required: false
default: ''
type: string
semver:
description: 'Semantic version. Leave empty to not use semantic versioning.'
required: false
default: ''
type: string
tags:
description: 'List of tags to apply to the image. Required if you do not use semantic versioning.'
required: false
default: |
type=raw,value=${{ github.sha }}
type: string
registry:
description: 'Registry for docker image to use. Defaults to GitHub container registry.'
required: false
default: ghcr.io
type: string
image_name:
description: 'Docker image name to use. Defaults to repository name.'
required: false
default: ${{ github.repository }}
type: string
registry_username:
description: 'Username to use for registry login. Defaults to Github actor.'
required: false
default: ${{ github.actor }}
type: string
registry_token:
description: 'Token to use for registry login. Defaults to GITHUB_TOKEN.'
required: false
default: null
type: string

jobs:
build:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

# Docker tagging based on semantic versioning or provided data
- name: Docker meta based on SemVer
id: meta-semver
if: ${{ inputs.semver != '' }}
uses: docker/metadata-action@v5
with:
images: ${{ inputs.registry }}/${{ inputs.image_name }}
tags: |
type=raw,value=latest
type=raw,value=${{ github.sha }}
type=semver,pattern={{major}},value=${{ inputs.semver }}
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.semver }}
type=semver,pattern={{version}},value=${{ inputs.semver }}
# Docker tagging based on provided data
- name: Docker meta based on provided data
id: meta-custom
if: ${{ inputs.semver == '' }}
uses: docker/metadata-action@v5
with:
images: ${{ inputs.registry }}/${{ inputs.image_name }}
tags: ${{ inputs.tags }}

# Set up Docker for build and push
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registry }}
username: ${{ inputs.registry_username || github.actor }}
password: ${{ inputs.registry_token || secrets.GITHUB_TOKEN }}

# Build and push the image
- name: Build and push
uses: docker/build-push-action@v5
with:
file: ${{ inputs.dockerfile }}
context: ${{ inputs.context }}
push: true
build-args: ${{ inputs.arguments }}
tags: ${{ steps.meta-semver.outputs.tags || steps.meta-custom.outputs.tags }}
labels: ${{ steps.meta-semver.outputs.labels || steps.meta-custom.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
76 changes: 76 additions & 0 deletions .github/workflows/semver-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Semantic Versioning Release

on:
push:
branches:
- main
workflow_call:
secrets:
RELEASE_GH_TOKEN:
description: "GitHub Token. Used to authenticate with GitHub at release step. This will overwrite the use of the default GitHub token."
required: false
BUILD_GH_TOKEN:
description: "GitHub Token. Used to authenticate with GitHub at build step. This will overwrite the use of the default GitHub token."
outputs:
version:
description: "The version of the release. Will be null if no release was made."
value: ${{ jobs.semantic-realease.outputs.version }}

jobs:
semantic-realease:
name: Semantic release
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
id-token: write
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Detect Gradle
id: gradle
run: echo "gradle=$(if [ -f "gradlew" ]; then echo "true"; else echo "false"; fi)" >> $GITHUB_OUTPUT
- name: Setup Java
uses: actions/setup-java@v4
if: steps.gradle.outputs.gradle == 'true'
with:
java-version: "21"
distribution: "temurin"
- name: Setup Gradle
if: steps.gradle.outputs.gradle == 'true'
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
- name: Prepare gradlew
if: steps.gradle.outputs.gradle == 'true'
run: chmod +x gradlew
- name: build and test
if: steps.gradle.outputs.gradle == 'true'
run: ./gradlew build
env:
GITHUB_TOKEN: ${{ secrets.BUILD_GH_TOKEN || secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "21"
cache: "npm"
- name: Install dependencies
run: npm clean-install --force
- name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
run: npm audit signatures
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_GH_TOKEN || secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.RELEASE_GH_TOKEN || secrets.GITHUB_TOKEN }}
run: npx semantic-release | tee semantic-release.log
- name: Archive release log
uses: actions/upload-artifact@v4
with:
name: semantic-release.log
path: semantic-release.log
- name: Get version
id: version
run: echo version=$(cat semantic-release.log | grep -oP "next release version is \K.*") >> $GITHUB_OUTPUT
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
36 changes: 36 additions & 0 deletions .releaserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"branches": [
"main",
{
"name": "develop",
"prerelease": "r"
}
],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/release-notes-generator",
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/github",
{
"successComment": false
}
],
[
"@semantic-release/npm",
{
"npmPublish": false
}
],
"@semantic-release/git"
]
}
148 changes: 146 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,146 @@
# ci
Centralized CI solution
# CI/CD GitHub Actions

Handles continues integration / continues development

## Versioning

The project uses [Semantic versioning](https://semver.org/), and the version is determined using [Semantic release](https://semantic-release.gitbook.io/semantic-release/).

You can use the version of the release, to lock in the version of the action, that you want to use.

Please only use `main` as the version, if you want to use the latest version, as it may be unstable or updated in a way that breaks your workflow.

## Available actions

### Semver release

This action will run Semantic Release to determine the next version of the package and create a new release.

#### Pre-requisites

Semver release pipeline requires a node project to be initiated in the repository.

<details>
<summary>Node project setup</summary>

Initialize a project with npm:

```bash
npm init -y
```

The following packages need to be installed:

```bash
npm install --save-dev @semantic-release/commit-analyzer @semantic-release/git @semantic-release/github @semantic-release/npm @semantic-release/release-notes-generator conventional-changelog-conventionalcommits
```

The following configuration needs to be added to a new file `.releaserc.json`:

```json
{
"branches": [
"main",
{
"name": "develop",
"prerelease": "r"
}
],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/release-notes-generator",
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/github",
{
"successComment": false
}
],
[
"@semantic-release/npm",
{
"npmPublish": false
}
],
"@semantic-release/git"
]
}
```

*This file is the default configuration and can be changed to fit the needs of the project.*

A `.gitignore` file should be added to the repository to ignore the `node_modules` folder, created by NPM.

```gitignore
node_modules
```

</details>


#### Inputs

- `GH_TOKEN`: The GitHub token to use for authentication. Defaults to the default GitHub token.

#### Outputs

- `version`: The version that was released. This may be null if no release was created.

#### Example usage

**Usage of the action:**

```yaml
release:
name: Release
uses: the0mikkel/ci/.github/workflows/[email protected]
```
### Docker build and push
This action will build a Docker image and push it to the GitHub Container Registry.
Currently, it will push to the same image name as the repository name, but allows for specifying the tags.
It by defaults sets tags for latest, sha and version numbers.
#### Pre-requisites
The action requires a Dockerfile to be present in the repository.
Where it is located can be specified in the action.
#### Inputs
- `dockerfile`: The path to the Dockerfile. Defaults to `./Dockerfile`.
- `context`: The build context for the Docker build. Defaults to `.`.
- `args`: Build arguments to pass to the Docker build. Defaults to an empty string.
Example: `VERSION=1.0.0`
- `semver`: The version to tag the image with. Leave empty, if you don't want to tag the image with the version. Defaults to an empty string.
Example: `1.0.0` or `${{ steps.release.outputs.version }}`
- `tags`: Additional tags to add to the image. Defaults to `type=raw,value=${{ github.sha }}`
- `registry`: What registry to use. Defaults to GitHub container registry `ghcr.io`
- `image_name`: Name of image. Defaults to GitHub repository `${{ github.repository }}`
- `registry_username`: Username to use for registry login. Defaults to Github actor.
- `registry_token`: Token to use for registry login. Defaults to GITHUB_TOKEN.

#### Example usage

**Usage of the action:**

```yaml
docker:
name: Docker
needs:
- release
uses: the0mikkel/ci/.github/workflows/[email protected]
with:
semver: ${{ needs.release.outputs.version }}
```
Loading

0 comments on commit 1af6b1e

Please sign in to comment.