Skip to content

Commit de8a981

Browse files
authored
Add Github Actions (#1)
1 parent 2080577 commit de8a981

File tree

10 files changed

+533
-1
lines changed

10 files changed

+533
-1
lines changed

.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.DS_Store
2+
*.o
3+
.so
4+
*.dylib
5+
build
6+
7+
.vscode/*
8+
!.vscode/c_cpp_properties.json
9+
!.vscode/launch.json
10+
!.vscode/settings.json
11+
!.vscode/tasks.json

.github/workflows/autotag.yaml

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
name: Auto Tag
2+
3+
permissions:
4+
contents: write
5+
pull-requests: read
6+
7+
on:
8+
pull_request:
9+
types: [closed]
10+
11+
workflow_dispatch:
12+
inputs:
13+
pullNumber:
14+
description: Pull request number (i.e. 1)
15+
required: true
16+
dryRun:
17+
description: Dryrun
18+
default: "true"
19+
type: choice
20+
options:
21+
- "true"
22+
- "false"
23+
24+
jobs:
25+
check:
26+
runs-on: ubuntu-latest
27+
if: (github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true))
28+
outputs:
29+
PULL_SHA: ${{ steps.check-pr.outputs.PULL_SHA }}
30+
RELEASE_TYPE: ${{ steps.check-pr.outputs.RELEASE_TYPE }}
31+
NEXT_TAG: ${{ steps.next-tag.outputs.NEXT_TAG }}
32+
steps:
33+
- name: Check pull request
34+
id: check-pr
35+
uses: actions/github-script@v7
36+
with:
37+
retries: 3
38+
script: |
39+
console.log('github.event_name', '${{ github.event_name }}')
40+
let pullNumber
41+
if('${{ github.event_name }}' == 'workflow_dispatch') {
42+
pullNumber = '${{ github.event.inputs.pullNumber }}'
43+
} else if('${{ github.event_name }}' == 'pull_request' && '${{ github.event.pull_request.merged }}' == 'true') {
44+
pullNumber = '${{ github.event.pull_request.number }}'
45+
} else {
46+
console.log('no pull number found')
47+
return
48+
}
49+
console.log('pullNumber', pullNumber)
50+
51+
const prRes = await github.rest.pulls.get({
52+
owner: context.repo.owner,
53+
repo: context.repo.repo,
54+
pull_number: pullNumber
55+
})
56+
if(prRes.status != 200) {
57+
console.log('prRes', JSON.stringify(prRes))
58+
core.setFailed(`failed to retrieve pull request: ${prRes.status}`)
59+
return
60+
}
61+
62+
const merged = (prRes.data != undefined && prRes.data.merged != undefined) ? prRes.data.merged : false
63+
if('${{ github.event_name }}' == 'workflow_dispatch' && !merged) {
64+
core.setFailed(`pull request #${pullNumber} is not merged (only merged PRs are allowed)`)
65+
return
66+
}
67+
68+
const labels = (prRes.data != undefined && prRes.data.labels != undefined) ? prRes.data.labels : []
69+
let releaseType
70+
if(labels.find(label => label.name == "release:major") != undefined) {
71+
releaseType = 'major'
72+
core.setOutput('RELEASE_TYPE', 'major')
73+
} else if(labels.find(label => label.name == "release:minor") != undefined) {
74+
releaseType = 'minor'
75+
core.setOutput('RELEASE_TYPE', 'minor')
76+
} else if(labels.find(label => label.name == "release:patch") != undefined) {
77+
releaseType = 'patch'
78+
} else {
79+
console.log('pull request does not have release labels')
80+
return
81+
}
82+
console.log('RELEASE_TYPE', releaseType)
83+
core.setOutput('RELEASE_TYPE', releaseType)
84+
85+
const pullSHA = (prRes.data != undefined && prRes.data.head != undefined && prRes.data.head.sha != undefined) ? prRes.data.head.sha : ''
86+
console.log('PULL_SHA', pullSHA)
87+
core.setOutput('PULL_SHA', pullSHA)
88+
89+
- name: Checkout code
90+
uses: actions/checkout@v4
91+
if: ${{ steps.check-pr.outputs.RELEASE_TYPE != '' }}
92+
with:
93+
fetch-depth: 0 # Ref: https://github.com/actions/checkout/issues/100
94+
95+
- name: Get current tag
96+
id: current-tag
97+
uses: "WyriHaximus/github-action-get-previous-tag@04e8485ecb6487243907e330d522ff60f02283ce" # v1.4.0 - latest as of 2025-04-27
98+
if: ${{ steps.check-pr.outputs.RELEASE_TYPE != '' }}
99+
with:
100+
fallback: v0.0.0
101+
102+
- name: Determine next semver version
103+
id: next-semver-version
104+
uses: madhead/semver-utils@36d1e0ed361bd7b4b77665de8093092eaeabe6ba # v4.3.0 - latest as of 2025-04-27
105+
if: ${{ steps.check-pr.outputs.RELEASE_TYPE != '' }}
106+
with:
107+
version: ${{ steps.current-tag.outputs.tag }}
108+
109+
- name: Determine next tag
110+
id: next-tag
111+
uses: actions/github-script@v7
112+
if: ${{ steps.check-pr.outputs.RELEASE_TYPE != '' }}
113+
with:
114+
script: |
115+
console.log('semver release: ${{ steps.next-semver-version.outputs.release }}')
116+
console.log('semver major: ${{ steps.next-semver-version.outputs.major }}')
117+
console.log('semver minor: ${{ steps.next-semver-version.outputs.minor }}')
118+
console.log('semver patch: ${{ steps.next-semver-version.outputs.patch }}')
119+
console.log('semver inc-major: ${{ steps.next-semver-version.outputs.inc-major }}')
120+
console.log('semver inc-minor: ${{ steps.next-semver-version.outputs.inc-minor }}')
121+
console.log('semver inc-patch: ${{ steps.next-semver-version.outputs.inc-patch }}')
122+
123+
let nextTag
124+
if('${{ steps.check-pr.outputs.RELEASE_TYPE }}' == 'major') {
125+
nextTag = '${{ steps.next-semver-version.outputs.inc-major }}'
126+
} else if('${{ steps.check-pr.outputs.RELEASE_TYPE }}' == 'minor') {
127+
nextTag = '${{ steps.next-semver-version.outputs.inc-minor }}'
128+
} else if('${{ steps.check-pr.outputs.RELEASE_TYPE }}' == 'patch') {
129+
nextTag = '${{ steps.next-semver-version.outputs.inc-patch }}'
130+
} else {
131+
core.setFailed('invalid RELEASE_TYPE: ${{ steps.check-pr.outputs.RELEASE_TYPE }}')
132+
return
133+
}
134+
console.log('nextTag', nextTag)
135+
core.setOutput('NEXT_TAG', nextTag)
136+
137+
tag:
138+
runs-on: ubuntu-latest
139+
needs: check
140+
if: ${{ needs.check.outputs.NEXT_TAG != '' }}
141+
steps:
142+
- name: Create tag
143+
id: create-tag
144+
uses: actions/github-script@v7
145+
with:
146+
github-token: ${{ secrets.PAT_WORKFLOW }}
147+
retries: 3
148+
script: |
149+
if('${{ github.event.inputs.dryRun }}' == 'true') {
150+
console.log('skipping tag creation due to dryrun')
151+
return
152+
}
153+
const createTagRes = await github.rest.git.createTag({
154+
owner: context.repo.owner,
155+
repo: context.repo.repo,
156+
tag: 'v${{ needs.check.outputs.NEXT_TAG }}',
157+
message: 'v${{ needs.check.outputs.NEXT_TAG }}',
158+
object: '${{ needs.check.outputs.PULL_SHA }}',
159+
type: 'commit',
160+
tagger: {
161+
name: '${{ secrets.GIT_USER_NAME }}',
162+
email: '${{ secrets.GIT_USER_EMAIL }}'
163+
}
164+
})
165+
if(createTagRes.status != 201) {
166+
console.log('createTagRes', JSON.stringify(createTagRes))
167+
core.setFailed(`failed to create tag: ${createTagRes.status}`)
168+
return
169+
}
170+
console.log('new tag', createTagRes.data.tag)
171+
console.log('new tag sha', createTagRes.data.sha)
172+
173+
const createRefRes = await github.rest.git.createRef({
174+
owner: context.repo.owner,
175+
repo: context.repo.repo,
176+
ref: `refs/tags/${createTagRes.data.tag}`,
177+
sha: createTagRes.data.sha
178+
})
179+
if(createRefRes.status != 201) {
180+
console.log('createRefRes', JSON.stringify(createRefRes))
181+
core.setFailed(`failed to create reference: ${createRefRes.status}`)
182+
return
183+
}
184+
console.log('new tag ref', createRefRes.data.ref)

.github/workflows/release.yaml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Release
2+
3+
permissions:
4+
contents: write
5+
6+
on:
7+
push:
8+
tags: ["v*.*.*"]
9+
10+
workflow_dispatch:
11+
inputs:
12+
releaseTag:
13+
description: Existing git tag (i.e. v0.1.0)
14+
required: true
15+
dryRun:
16+
description: Dryrun
17+
default: "true"
18+
type: choice
19+
options:
20+
- "true"
21+
- "false"
22+
23+
jobs:
24+
check:
25+
runs-on: ubuntu-latest
26+
if: (github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref_type == 'tag'))
27+
outputs:
28+
RELEASE_TAG: ${{ steps.check-tag.outputs.RELEASE_TAG }}
29+
REPO_NAME: ${{ steps.check-tag.outputs.REPO_NAME }}
30+
steps:
31+
- name: Check release tag
32+
id: check-tag
33+
uses: actions/github-script@v7
34+
with:
35+
script: |
36+
console.log('github.event_name', '${{ github.event_name }}')
37+
console.log('github.ref_type', '${{ github.ref_type }}')
38+
let releaseTag
39+
if('${{ github.event_name }}' == 'workflow_dispatch') {
40+
releaseTag = '${{ github.event.inputs.releaseTag }}'
41+
} else if('${{ github.event_name }}' == 'push' && '${{ github.ref_type }}' == 'tag') {
42+
releaseTag = '${{ github.ref }}'.replace(/^refs\/tags\//, '');
43+
} else {
44+
console.log('no semver tag found')
45+
return
46+
}
47+
console.log('RELEASE_TAG', releaseTag)
48+
core.setOutput('RELEASE_TAG', releaseTag)
49+
console.log('REPO_NAME', context.repo.repo)
50+
core.setOutput('REPO_NAME', context.repo.repo)
51+
52+
- name: Check tag semver
53+
id: check-tag-semver
54+
uses: madhead/semver-utils@36d1e0ed361bd7b4b77665de8093092eaeabe6ba # v4.3.0 - latest as of 2025-04-27
55+
if: ${{ steps.check-tag.outputs.RELEASE_TAG != '' }}
56+
with:
57+
version: ${{ steps.check-tag.outputs.RELEASE_TAG }}
58+
lenient: false # fail on error
59+
60+
release:
61+
runs-on: ubuntu-latest
62+
needs: check
63+
if: ${{ needs.check.outputs.RELEASE_TAG != '' }}
64+
steps:
65+
- name: Make a release
66+
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2 - latest as of 2025-04-27
67+
if: github.event.inputs.dryRun != 'true'
68+
with:
69+
tag_name: ${{ needs.check.outputs.RELEASE_TAG }}

.github/workflows/test.yaml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- '*'
9+
pull_request:
10+
branches:
11+
- '*'
12+
13+
workflow_dispatch:
14+
inputs:
15+
logLevel:
16+
description: Log Level
17+
default: info
18+
type: choice
19+
options:
20+
- debug
21+
- error
22+
- fatal
23+
- info
24+
- panic
25+
- warning
26+
environment:
27+
description: Environment
28+
default: test
29+
30+
jobs:
31+
32+
test-amd64:
33+
runs-on: ubuntu-latest
34+
strategy:
35+
matrix:
36+
include:
37+
- platform: linux/amd64
38+
dockerfile: Dockerfile.amd64
39+
tag: tinyclib:amd64
40+
test: amd64
41+
42+
steps:
43+
- name: Docker Setup QEMU
44+
if: matrix.platform != 'linux/amd64'
45+
uses: docker/[email protected] # v3.6.0 - latest as of 2025-04-27
46+
with:
47+
platforms: all
48+
49+
- name: Docker Setup Buildx
50+
uses: docker/[email protected] # v3.10.0 - latest as of 2025-04-27
51+
52+
- name: Checkout code
53+
uses: actions/checkout@v4 # v4.2.2 - latest as of 2025-04-27
54+
55+
- name: Create Buildx
56+
run: |
57+
docker buildx create --name tests --use
58+
docker buildx inspect --bootstrap
59+
60+
- name: Build images
61+
run: |
62+
docker images
63+
docker buildx ls --no-trunc
64+
docker buildx build --platform ${{ matrix.platform }} -f scripts/tests/docker/${{ matrix.dockerfile }} -t ${{ matrix.tag }} . --load
65+
docker images
66+
67+
- name: Test
68+
run: |
69+
for platform in ${{ matrix.platform }}; do
70+
for tag in ${{ matrix.tag }}; do
71+
echo "Running container for platform: $platform, tag: $tag"
72+
docker run --platform $platform $tag
73+
done
74+
done
75+
76+
test-arm64:
77+
runs-on: ubuntu-24.04-arm
78+
strategy:
79+
matrix:
80+
include:
81+
- platform: linux/arm64
82+
dockerfile: Dockerfile.arm64
83+
tag: tinyclib:arm64
84+
test: arm64
85+
86+
- platform: linux/arm/v6
87+
dockerfile: Dockerfile.armv6
88+
tag: tinyclib:armv6
89+
test: armv6
90+
91+
- platform: linux/arm/v7
92+
dockerfile: Dockerfile.armv7
93+
tag: tinyclib:armv7
94+
test: armv7
95+
96+
- platform: linux/arm64/v8
97+
dockerfile: Dockerfile.armv8
98+
tag: tinyclib:armv8
99+
test: armv8
100+
101+
steps:
102+
- name: Docker Setup Buildx
103+
uses: docker/[email protected] # v3.10.0 - latest as of 2025-04-27
104+
105+
- name: Checkout code
106+
uses: actions/checkout@v4 # v4.2.2 - latest as of 2025-04-27
107+
108+
- name: Create Buildx
109+
run: |
110+
docker buildx create --name tests --use
111+
docker buildx inspect --bootstrap
112+
113+
- name: Build images
114+
run: |
115+
docker images
116+
docker buildx ls --no-trunc
117+
docker buildx build --platform ${{ matrix.platform }} -f scripts/tests/docker/${{ matrix.dockerfile }} -t ${{ matrix.tag }} . --load
118+
docker images
119+
120+
- name: Test
121+
run: |
122+
for platform in ${{ matrix.platform }}; do
123+
for tag in ${{ matrix.tag }}; do
124+
echo "Running container for platform: $platform, tag: $tag"
125+
docker run --platform $platform $tag
126+
done
127+
done

0 commit comments

Comments
 (0)