ci: switch to actions (#234)

- closes #89

Reviewed-on: https://codeberg.org/forgejo-contrib/forgejo-helm/pulls/234
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-committed-by: Michael Kriese <michael.kriese@visualon.de>
This commit is contained in:
Michael Kriese 2023-12-07 15:56:12 +00:00 committed by Michael Kriese
parent a8c4af66f5
commit 3a1928c788
16 changed files with 456 additions and 168 deletions

View file

@ -0,0 +1,26 @@
# action.yml
name: setup-docker
description: 'setup docker'
runs:
using: 'composite'
steps:
- shell: bash
name: create cache
run: |
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update -qq
apt-get -q install -qq \
containerd.io \
docker-ce \
docker-ce-cli \
;
- shell: bash
run: docker info

View file

@ -0,0 +1,13 @@
# action.yml
name: setup-node
description: 'setup node'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: 'npm'
- shell: bash
run: npm ci

View file

@ -0,0 +1,26 @@
# action.yml
name: setup
description: 'setup system'
runs:
using: 'composite'
steps:
- shell: bash
name: create cache
run: |
mkdir -p /opt/hostedtoolcache
mkdir -p /srv/forgejo-renovate/.cache/act/tool_cache
- shell: bash
name: install deps
run: |
apt-get update -qq
apt-get -q install -qq \
ca-certificates \
curl \
gnupg \
make \
python3 \
python3-wheel \
python3-venv \
unzip \
;

View file

@ -0,0 +1,178 @@
name: build
on:
pull_request:
push:
branches:
- main
- release/**
tags:
- v*
permissions:
contents: read
env:
HELM_VERSION: v3.11.2 # renovate: datasource=github-releases depName=helm packageName=helm/helm
HELM_UNITTEST_VERSION: v0.3.6 # renovate: datasource=github-releases depName=helm-unittest packageName=helm-unittest/helm-unittest
HELM_CHART_TESTING_VERSION: v3.10.1 # renovate: datasource=github-releases depName=chart-testing packageName=helm/chart-testing
KIND_VERSION: v0.20.0 # renovate: datasource=github-releases depName=kind packageName=kubernetes-sigs/kind
KUBECTL_VERSION: v1.28.0 # renovate: datasource=github-releases depName=kubectl packageName=kubernetes/kubernetes
jobs:
lint-node:
runs-on: docker
steps:
- run: cat /etc/os-release
- uses: actions/checkout@v4
with:
show-progress: false
- uses: ./.forgejo/actions/setup
- uses: ./.forgejo/actions/setup-node
- run: npm run prettier
- run: npx markdownlint-cli .
- run: make readme
- run: git diff --exit-code --name-only README.md
lint-helm:
runs-on: docker
steps:
- run: cat /etc/os-release
- run: ps axf
- uses: actions/checkout@v4
with:
show-progress: false
fetch-depth: 0
- uses: ./.forgejo/actions/setup
- name: install chart-testing
uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1
with:
version: ${{ env.HELM_CHART_TESTING_VERSION }}
- name: install helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
with:
version: ${{ env.HELM_VERSION }}
- name: install helm-unittest
run: helm plugin install --version ${{ env.HELM_UNITTEST_VERSION }} https://github.com/helm-unittest/helm-unittest
- run: helm dependency build
- run: yamllint -f colored .
- run: helm lint
- run: helm template --debug gitea-helm .
- run: make unittests
- run: ct lint --config tools/ct.yml --charts .
e2e:
runs-on: k8s
strategy:
matrix:
k8s:
# from https://hub.docker.com/r/kindest/node/tags
# - v1.25.3 # renovate: kindest
- v1.28.0 # renovate: kindest
steps:
- run: cat /etc/os-release
- uses: actions/checkout@v4
with:
show-progress: false
fetch-depth: 0
- uses: ./.forgejo/actions/setup
- name: install helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
with:
version: ${{ env.HELM_VERSION }}
- name: Install chart-testing
# TODO: pin to version when this is released: https://github.com/helm/chart-testing-action/pull/137
uses: helm/chart-testing-action@86b540ddcecb3cc009fa2bc0f44fa5b33e9751a2 # main
with:
version: ${{ env.HELM_CHART_TESTING_VERSION }}
- uses: ./.forgejo/actions/setup-docker
- name: Create kind cluster
uses: helm/kind-action@dda0770415bac9fc20092cacbc54aa298604d140 # v1.8.0
with:
node_image: kindest/node:${{ matrix.k8s }}
kubectl_version: ${{ env.KUBECTL_VERSION }}
version: ${{ env.KIND_VERSION }}
- run: kubectl get no -o wide
- name: install chart
run: ct install --config tools/ct.yml --charts .
# # Catch-all required check for test matrix
test-success:
needs:
- lint-node
- lint-helm
- e2e
runs-on: docker
timeout-minutes: 1
if: always()
steps:
- name: Fail for failed or cancelled lint-node
if: |
needs.lint-node.result == 'failure' ||
needs.lint-node.result == 'cancelled'
run: exit 1
- name: Fail for failed or cancelled lint-helm
if: |
needs.lint-helm.result == 'failure' ||
needs.lint-helm.result == 'cancelled'
run: exit 1
- name: Fail for failed or cancelled e2e
if: |
needs.e2e.result == 'failure' ||
needs.e2e.result == 'cancelled'
run: exit 1
publish:
runs-on: docker
needs:
- test-success
if: ${{ github.ref_type == 'tag' }}
steps:
- uses: actions/checkout@v4
with:
show-progress: false
- uses: ./.forgejo/actions/setup
- uses: ./.forgejo/actions/setup-node
- name: install helm
uses: https://github.com/azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
with:
version: v3.13.2 # renovate: datasource=github-releases depName=helm packageName=helm/helm
- run: helm dependency build
- run: helm package --version "${GITHUB_REF_NAME#v}" -d tmp/ ./
- name: login to codeberg packages
run: echo ${TOKEN} | helm registry login -u viceice --password-stdin codeberg.org/forgejo-contrib
env:
TOKEN: ${{secrets.token}}
- name: publish forgejo helm chart
run: helm push tmp/forgejo-${GITHUB_REF_NAME#v}.tgz oci://codeberg.org/forgejo-contrib
- name: publish forgejo release
run: npm run forgejo:release

1
.node-version Normal file
View file

@ -0,0 +1 @@
20.10.0

View file

@ -1,5 +1,9 @@
{
"yaml.schemas": {
"https://json.schemastore.org/github-workflow.json": [
".github/workflows/*",
".forgejo/workflows/*"
],
"https://raw.githubusercontent.com/helm-unittest/helm-unittest/v0.3.6/schema/helm-testsuite.json": [
"/unittests/**/*.yaml"
]

View file

@ -1,49 +0,0 @@
platform: linux/amd64
when:
event:
- pull_request
- push
- tag
branch:
- main
- release/**
services:
docker:
image: docker:24.0.7-dind
pull: true
environment:
DOCKER_TLS_CERTDIR: ''
matrix:
k8s:
# from https://hub.docker.com/r/kindest/node/tags
# - v1.25.3 # renovate: kindest
- v1.28.0 # renovate: kindest
pipeline:
create-cluster:
image: alpine:3.18.5
pull: true
environment:
DOCKER_HOST: tcp://docker:2375
commands:
- apk add docker-cli kind
- export KUBECONFIG=$${CI_WORKSPACE}/kube.config
- sleep 15s
- docker info
- kind create cluster --config e2e/kind.cluster.yml --image kindest/node:${k8s} --wait 1m
- kind get clusters
- docker ps
# replace localhost or 0.0.0.0 in the kubeconfig file with "docker", in order to be able to reach the cluster through the docker service
- sed -i -E -e 's/localhost|0\.0\.0\.0/docker/g' $${KUBECONFIG}
ct-install:
image: quay.io/helmpack/chart-testing:v3.10.1
pull: true
commands:
- git fetch --no-tags --filter=blob:none origin
- export KUBECONFIG=$${CI_WORKSPACE}/kube.config
- kubectl get no -o wide
- ct install --config tools/ct.yml --charts .

View file

@ -1,71 +0,0 @@
platform: linux/amd64
when:
event:
- pull_request
- tag
- push
branch:
- main
- release/**
pipeline:
prettier:
image: alpine:3.18.5
pull: true
commands:
- apk add nodejs npm
- npm ci
- npm run prettier
- npx markdownlint-cli .
deps:
image: alpine:3.18.5
pull: true
commands:
- apk add helm
- helm dependency build
helm-lint:
image: alpine:3.18.5
pull: true
commands:
- apk add helm
- helm lint
helm-template:
image: alpine:3.18.5
pull: true
commands:
- apk add helm
- helm template --debug gitea-helm .
helm-unittests:
image: alpine:3.18.5
pull: true
commands:
- apk add make helm git bash
- helm plugin install --version v0.3.6 https://github.com/helm-unittest/helm-unittest
- helm dependency update
- make unittests
verify-readme:
image: alpine:3.18.5
pull: true
commands:
- apk add make nodejs npm git
- make readme
- git diff --exit-code --name-only README.md
yaml-lint:
image: quay.io/helmpack/chart-testing:v3.10.1
pull: true
commands:
- yamllint -f colored .
ct-lint:
image: quay.io/helmpack/chart-testing:v3.10.1
pull: true
commands:
- git fetch --no-tags --filter=blob:none origin
- ct lint --config tools/ct.yml --charts .

View file

@ -1,47 +0,0 @@
platform: linux/amd64
depends_on:
- lint
- e2e
when:
event:
- tag
tag: v*
pipeline:
generate-chart:
image: alpine:3.18.5
pull: true
commands:
- apk add git nodejs npm helm
- helm dependency build
- rm -rf tmp/
- helm package --version "${CI_COMMIT_TAG##v}" -d tmp/ ./
- npm ci
- npm run changelog "${CI_COMMIT_TAG##v}" tmp/changelog.md
secrets:
- token
publish-release:
image: codeberg.org/woodpecker-plugins/gitea-release:0.3.1
pull: true
settings:
base_url: https://codeberg.org
api_key:
from_secret: token
files: tmp/*.tgz
title: ${CI_COMMIT_TAG##v}
file_exists: fail
note: tmp/changelog.md
target: main
publish-chart:
image: alpine:3.18.5
pull: true
commands:
- apk add helm
- echo $${TOKEN} | helm registry login -u viceice --password-stdin codeberg.org/forgejo-contrib
- helm push tmp/forgejo-${CI_COMMIT_TAG##v}.tgz oci://codeberg.org/forgejo-contrib
secrets:
- token

19
package-lock.json generated
View file

@ -8,6 +8,7 @@
"license": "MIT",
"devDependencies": {
"@bitnami/readme-generator-for-helm": "^2.4.2",
"clipanion": "^3.2.1",
"conventional-changelog-conventionalcommits": "^7.0.0",
"conventional-changelog-core": "^7.0.0",
"husky": "^8.0.3",
@ -279,6 +280,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/clipanion": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/clipanion/-/clipanion-3.2.1.tgz",
"integrity": "sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==",
"dev": true,
"dependencies": {
"typanion": "^3.8.0"
},
"peerDependencies": {
"typanion": "*"
}
},
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -2116,6 +2129,12 @@
"node": ">=8.0"
}
},
"node_modules/typanion": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz",
"integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==",
"dev": true
},
"node_modules/type-fest": {
"version": "4.8.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.3.tgz",

View file

@ -10,6 +10,7 @@
},
"scripts": {
"changelog": "node tools/changelog.mjs",
"forgejo:release": "node tools/gitea-release.js",
"prepare": "husky install",
"prettier": "prettier --check --ignore-unknown --cache \"**/*.*\"",
"prettier-fix": "prettier --write --ignore-unknown --cache \"**/*.*\"",
@ -18,6 +19,7 @@
},
"devDependencies": {
"@bitnami/readme-generator-for-helm": "^2.4.2",
"clipanion": "^3.2.1",
"conventional-changelog-conventionalcommits": "^7.0.0",
"conventional-changelog-core": "^7.0.0",
"husky": "^8.0.3",

View file

@ -38,6 +38,18 @@
"matchManagers": ["npm"],
"matchDepTypes": ["devDependencies"],
"automerge": true
},
{
"description": "Separate minor and patch updates for kindest",
"matchPackageNames": ["kindest/node"],
"separateMinorPatch": true
},
{
"description": "Require approval and no automerge for kindest major and minor updates",
"matchPackageNames": ["kindest/node"],
"matchUpdateTypes": ["major", "minor"],
"dependencyDashboardApproval": true,
"automerge": false
}
],
"customManagers": [
@ -69,6 +81,16 @@
"https:\\/\\/raw\\.githubusercontent\\.com\\/(?<depName>[^\\s]+?)\\/(?<currentValue>v[0-9.]+?)\\/schema\\/helm-testsuite\\.json"
],
"datasourceTemplate": "github-releases"
},
{
"customType": "regex",
"description": "Update kindest kubernetes references",
"fileMatch": ["^\\.forgejo\\/workflows\\/[^/]+\\.ya?ml$"],
"matchStrings": [
" +- (?<currentValue>v\\d+\\.\\d+\\.\\d+) # renovate: kindest\\n"
],
"depNameTemplate": "kindest/node",
"datasourceTemplate": "docker"
}
]
}

78
tools/changelog/util.js Normal file
View file

@ -0,0 +1,78 @@
import conventionalChangelogPreset from 'conventional-changelog-conventionalcommits';
import conventionalChangelogCore from 'conventional-changelog-core';
/**
* @type {import('conventional-changelog-core').Options}
*/
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
export const config = conventionalChangelogPreset({
types: [
{
type: 'feat',
section: 'Features',
},
{
type: 'feature',
section: 'Features',
},
{
type: 'fix',
section: 'Bug Fixes',
},
{
type: 'perf',
section: 'Performance Improvements',
},
{
type: 'revert',
section: 'Reverts',
},
{
type: 'docs',
section: 'Documentation',
},
{
type: 'style',
section: 'Styles',
},
{
type: 'chore',
section: 'Miscellaneous Chores',
},
{
type: 'refactor',
section: 'Code Refactoring',
},
{
type: 'test',
section: 'Tests',
},
{
type: 'build',
section: 'Build System',
},
{
type: 'ci',
section: 'Continuous Integration',
},
],
});
/**
*
* @param {string} version
* @param {boolean} onTag
* @returns
*/
export function getChangelog(version, onTag) {
return conventionalChangelogCore(
{
config,
releaseCount: onTag ? 2 : 1,
},
{ version, linkCompare: false },
undefined,
undefined,
{ headerPartial: '' },
);
}

View file

@ -1,4 +1,4 @@
# helm-extra-args: --timeout 600s
helm-extra-args: --timeout 600s
check-version-increment: false
debug: true
target-branch: main

83
tools/forgejo-release.js Normal file
View file

@ -0,0 +1,83 @@
import { Command, runExit } from 'clipanion';
import { getChangelog } from './changelog/util.js';
const api = 'https://https://codeberg.org/api/v1';
const repo = 'forgejo-contrib/forgejo-helm';
class GiteaReleaseCommand extends Command {
async execute() {
const token = process.env.GITHUB_TOKEN;
if (!token) {
this.context.stdout.write('GITHUB_TOKEN environment variable not set.\n');
return 1;
}
this.context.stdout.write(`Getting tag.\n`);
const tag = process.env.GITHUB_REF_NAME;
if (!tag) {
this.context.stdout.write(
'No tag found for this commit. Please tag the commit and try again.\n',
);
return 1;
}
this.context.stdout.write(`Checking remote tag ${tag}.\n`);
let resp = await fetch(`${api}/repos/${repo}/tags/${tag}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!resp.ok) {
this.context.stdout.write(`Tag ${tag} not found on remote.\n`);
return 1;
}
this.context.stdout.write(`Checking remote release ${tag}.\n`);
resp = await fetch(`${api}/repos/${repo}/releases/tags/${tag}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (resp.ok) {
this.context.stdout.write(`Release ${tag} already exists.\n`);
return 1;
} else if (resp.status !== 404) {
this.context.stdout.write(
`Error checking for release ${tag}.\n${resp.status}: ${resp.statusText}\n`,
);
return 1;
}
const stream = getChangelog(tag, true).setEncoding('utf8');
const changes = (await stream.toArray()).join('');
this.context.stdout.write(`Creating release ${tag}.\n`);
resp = await fetch(`${api}/repos/${repo}/releases`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
draft: false,
prerelease: tag.includes('-'),
tag_name: tag,
name: tag.replace(/^v/, ''),
body: changes,
target_commitish: 'main',
}),
});
if (!resp.ok) {
this.context.stdout.write(
`Error creating release ${tag}.\n${resp.status}: ${resp.statusText}\n`,
);
return 1;
}
}
}
void runExit(GiteaReleaseCommand);

3
tools/package.json Normal file
View file

@ -0,0 +1,3 @@
{
"type": "module"
}