Compare commits
56 Commits
2bef079d03
...
0.1.9
| Author | SHA1 | Date | |
|---|---|---|---|
| 3de301aa92 | |||
| 4dcbb11f20 | |||
| 9da134bdaf | |||
| 752bbb332f | |||
| 45404dc002 | |||
| 5a00763d8f | |||
| 4a79ce9d17 | |||
| 9d402578bd | |||
| 63ce59e604 | |||
| a566998180 | |||
| 1239cc5673 | |||
| 20a6099969 | |||
| c7141fc28f | |||
| c87e585918 | |||
| 8f4725e23f | |||
| f35c24857f | |||
| c233ef8975 | |||
| f32b345f58 | |||
| 0740dbf815 | |||
| 0efd7db43a | |||
| 705af709c4 | |||
| 1d396c8278 | |||
| 16b25970ff | |||
| 52601104b0 | |||
| 8312cff6ec | |||
| 8c11306f2b | |||
| 2ae96a5355 | |||
| fc76234379 | |||
| 0fa291f103 | |||
| db47775249 | |||
| 1be3b5b434 | |||
| 544ec4afe4 | |||
| 815c39c6a7 | |||
| ccec73e40a | |||
| 26394e5a54 | |||
| 8d9bd42f6c | |||
| 69d574955c | |||
| cbd63b7581 | |||
| ae84083eae | |||
| 2d3fd96768 | |||
| 95f0aca47e | |||
| b6c4d5ae4f | |||
| 5e011b3993 | |||
| 5f14554b1f | |||
| 416939fb82 | |||
| ccf833d698 | |||
| 5848f47c0e | |||
| b32a97ed9b | |||
| e853e22d1d | |||
| 83e35f5324 | |||
| 95257c17b9 | |||
| b51adf3410 | |||
| daa5dc58ed | |||
| 5ac7516672 | |||
| 622e8acdc5 | |||
| 6e26281fea |
@@ -16,109 +16,315 @@ on:
|
||||
required: true
|
||||
GIT_PAGES_PUBLISH_TOKEN:
|
||||
required: true
|
||||
DOCKER_USERNAME:
|
||||
required: false
|
||||
DOCKER_PASSWORD:
|
||||
required: true
|
||||
|
||||
env:
|
||||
GITEA_API_URL: ${{ fromJson(inputs.env_json).GITEA_API_URL }}
|
||||
GIT_PAGES_URL: ${{ fromJson(inputs.env_json).GIT_PAGES_URL }}
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
GIT_PAGES_PUBLISH_TOKEN: ${{ secrets.GIT_PAGES_PUBLISH_TOKEN }}
|
||||
REPO: ${{ github.repository }}
|
||||
DOCKER_REGISTRY: ${{ fromJson(inputs.env_json).DOCKER_REGISTRY || '' }}
|
||||
DOCKER_IMAGE_NAME: ${{ fromJson(inputs.env_json).DOCKER_IMAGE_NAME || '' }}
|
||||
DOCKER_UI_URL: ${{ fromJson(inputs.env_json).DOCKER_UI_URL || '' }}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
artifact_exists: ${{ steps.check.outputs.artifact_exists }}
|
||||
version: ${{ steps.check.outputs.version }}
|
||||
artifact_exists: ${{ steps.set-outputs.outputs.artifact_exists }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check existing artifact
|
||||
id: check
|
||||
- name: Set Gitea status to PENDING
|
||||
run: |
|
||||
VERSION=$(jq -r '.version' package.json)
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "===== gitea-ci-library - Check existing artifact | begin ====="
|
||||
bash scripts/report-status.sh pending "Checking version..." ci-check
|
||||
|
||||
- name: Check existing artifact and calculate version
|
||||
run: |
|
||||
RAW_VERSION=$(jq -r '.version' package.json)
|
||||
BASE_VERSION=$(echo "$RAW_VERSION" | cut -d'.' -f1-2)
|
||||
echo "gitea-ci-library - Tunnistettu Major.Minor versio: $BASE_VERSION"
|
||||
|
||||
TAGS_JSON=$(curl -s -f -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
|
||||
"${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/tags")
|
||||
|
||||
TAG=$(echo "$TAGS_JSON" | jq -r 'if type == "array" then .[] | select(.commit.sha == "${{ github.sha }}") | .name else empty end' | head -1)
|
||||
|
||||
mkdir -p /tmp/build-ctx
|
||||
|
||||
TAG=$(curl -s "$GITEA_API_URL/api/v1/repos/$GITHUB_REPOSITORY/tags" | \
|
||||
jq -r '.[] | select(.commit.sha == "'"$GITHUB_SHA"'") | .name' | head -1)
|
||||
if [ -n "$TAG" ]; then
|
||||
echo "artifact_exists=true" >> "$GITHUB_OUTPUT"
|
||||
echo "Commit already tagged as $TAG, skipping build"
|
||||
echo "ARTIFACT_EXISTS=true" > /tmp/build-ctx/build.env
|
||||
echo "NEXT_VERSION=$TAG" >> /tmp/build-ctx/build.env
|
||||
echo "gitea-ci-library - Artefakti löytyi jo tagilla: $TAG."
|
||||
else
|
||||
echo "artifact_exists=false" >> "$GITHUB_OUTPUT"
|
||||
echo "ARTIFACT_EXISTS=false" > /tmp/build-ctx/build.env
|
||||
|
||||
HIGHEST_PATCH=$(echo "$TAGS_JSON" | jq -r --arg bv "$BASE_VERSION." '
|
||||
if type == "array" then .[] | .name | select(startswith($bv)) | sub($bv; "") | tonumber else empty end' | sort -rn | head -1)
|
||||
|
||||
if [ -z "$HIGHEST_PATCH" ]; then NEXT_PATCH=0; else NEXT_PATCH=$((HIGHEST_PATCH + 1)); fi
|
||||
FULL_VERSION="${BASE_VERSION}.${NEXT_PATCH}"
|
||||
|
||||
echo "NEXT_VERSION=$FULL_VERSION" >> /tmp/build-ctx/build.env
|
||||
echo "gitea-ci-library - Uusi vapaa versio: $FULL_VERSION"
|
||||
fi
|
||||
|
||||
quality-gate:
|
||||
needs: [check]
|
||||
if: needs.check.outputs.artifact_exists == 'false'
|
||||
uses: niko/gitea-ci-library/.gitea/workflows/quality-gate.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
env_json: ${{ inputs.env_json }}
|
||||
bats-image: ${{ inputs.bats-image }}
|
||||
cucumber-node-image: ${{ inputs.cucumber-node-image }}
|
||||
- name: Set job outputs
|
||||
id: set-outputs
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
echo "artifact_exists=$ARTIFACT_EXISTS" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload build env artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: build-context
|
||||
path: /tmp/build-ctx/build.env
|
||||
retention-days: 1
|
||||
|
||||
- name: Set Gitea status to SUCCESS
|
||||
if: success()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
if [ "${ARTIFACT_EXISTS}" = "true" ]; then
|
||||
bash scripts/report-status.sh success "Skip build: version $NEXT_VERSION exists" ci-check
|
||||
else
|
||||
bash scripts/report-status.sh success "Build version $NEXT_VERSION required" ci-check
|
||||
fi
|
||||
|
||||
- name: Set Gitea status to FAILURE
|
||||
if: failure()
|
||||
run: bash scripts/report-status.sh failure "Check version FAILED" ci-check
|
||||
|
||||
# quality-gate:
|
||||
# needs: [check]
|
||||
# uses: niko/gitea-ci-library/.gitea/workflows/quality-gate.yml@main
|
||||
# secrets: inherit
|
||||
# with:
|
||||
# env_json: ${{ inputs.env_json }}
|
||||
# bats-image: ${{ inputs.bats-image }}
|
||||
# cucumber-node-image: ${{ inputs.cucumber-node-image }}
|
||||
|
||||
build:
|
||||
needs: [check, quality-gate]
|
||||
if: needs.check.outputs.artifact_exists == 'false'
|
||||
runs-on: ubuntu-latest
|
||||
# needs: [check, quality-gate]
|
||||
needs: [check]
|
||||
# Skipataan koko build jos artefakti löytyy jo
|
||||
if: needs.check.outputs.artifact_exists != 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build container
|
||||
run: |
|
||||
docker build -t "minimal:${{ needs.check.outputs.version }}" .
|
||||
mkdir -p /tmp/image
|
||||
docker save "minimal:${{ needs.check.outputs.version }}" -o /tmp/image/artifact.tar
|
||||
- name: Download build env
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-context
|
||||
path: /tmp/build-ctx
|
||||
|
||||
- name: Save Docker image for next job
|
||||
uses: actions/upload-artifact@v4
|
||||
- name: Check if build needed
|
||||
id: gatekeeper
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
if [ "${ARTIFACT_EXISTS}" = "true" ]; then
|
||||
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Set Gitea status to PENDING
|
||||
if: steps.gatekeeper.outputs.skip == 'false'
|
||||
run: |
|
||||
echo "===== gitea-ci-library - Docker Build | begin ====="
|
||||
bash scripts/report-status.sh pending "Building Docker image..." ci-docker-build
|
||||
|
||||
- name: Build container
|
||||
if: steps.gatekeeper.outputs.skip == 'false'
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
docker build \
|
||||
--label "git.commit=${{ github.sha }}" \
|
||||
--label "git.commitBy=${{ github.actor }}" \
|
||||
--label "build.date=${NOW}" \
|
||||
-t "${DOCKER_IMAGE_NAME}:${NEXT_VERSION}" .
|
||||
|
||||
- name: Report status SUCCESS
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && success()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
bash scripts/report-status.sh success "Docker build $NEXT_VERSION OK" ci-docker-build
|
||||
|
||||
- name: Report status FAILURE
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && failure()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
bash scripts/report-status.sh failure "Docker build $NEXT_VERSION FAILED" ci-docker-build
|
||||
|
||||
- name: Save Docker image
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && success()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
mkdir -p /tmp/image
|
||||
docker save "${DOCKER_IMAGE_NAME}:${NEXT_VERSION}" -o /tmp/image/artifact.tar
|
||||
|
||||
- name: Upload Docker image artifact
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && success()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docker-image
|
||||
path: /tmp/image/artifact.tar
|
||||
retention-days: 1
|
||||
|
||||
push:
|
||||
needs: [check, build]
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check, build]
|
||||
if: needs.check.outputs.artifact_exists != 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download build env
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-context
|
||||
path: /tmp/build-ctx
|
||||
|
||||
- name: Verify Build Status
|
||||
id: gatekeeper
|
||||
run: |
|
||||
BUILD_RESULT="${{ needs.build.result }}"
|
||||
source /tmp/build-ctx/build.env
|
||||
if [ "$BUILD_RESULT" != "success" ]; then
|
||||
echo "gitea-ci-library - Edellinen vaihe epäonnistui. Keskeytetään." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "${ARTIFACT_EXISTS}" = "true" ]; then
|
||||
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Load saved Docker image
|
||||
uses: actions/download-artifact@v4
|
||||
if: steps.gatekeeper.outputs.skip == 'false'
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: docker-image
|
||||
path: /tmp/image
|
||||
|
||||
- name: Push to Gitea Packages
|
||||
- name: Set Gitea status to PENDING
|
||||
if: steps.gatekeeper.outputs.skip == 'false'
|
||||
run: |
|
||||
VERSION="${{ needs.check.outputs.version }}"
|
||||
echo "===== gitea-ci-library - Docker Push | begin ====="
|
||||
bash scripts/report-status.sh pending "Pushing to registry..." ci-docker-push
|
||||
|
||||
- name: Push to Docker Registry
|
||||
if: steps.gatekeeper.outputs.skip == 'false'
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME || github.actor }}
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
docker load -i /tmp/image/artifact.tar
|
||||
REGISTRY=$(echo "$GITEA_API_URL" | sed 's|https://||')
|
||||
IMAGE="$REGISTRY/niko/gitea-ci-library/minimal:$VERSION"
|
||||
docker tag "minimal:$VERSION" "$IMAGE"
|
||||
docker login "$REGISTRY" -u niko -p "$GITEA_TOKEN"
|
||||
docker push "$IMAGE"
|
||||
docker logout "$REGISTRY"
|
||||
|
||||
REGISTRY="${DOCKER_REGISTRY:?DOCKER_REGISTRY not set in env.conf}"
|
||||
IMAGE="${DOCKER_IMAGE_NAME:?DOCKER_IMAGE_NAME not set in env.conf}"
|
||||
REGISTRY_HOST="${REGISTRY%%/*}"
|
||||
|
||||
FULL_IMAGE="${REGISTRY}/${IMAGE}:${NEXT_VERSION}"
|
||||
echo "Pushing ${FULL_IMAGE} ..."
|
||||
|
||||
docker tag "${DOCKER_IMAGE_NAME}:${NEXT_VERSION}" "$FULL_IMAGE"
|
||||
echo "$DOCKER_PASSWORD" | docker login "$REGISTRY_HOST" -u "$DOCKER_USERNAME" --password-stdin
|
||||
docker push "$FULL_IMAGE"
|
||||
docker logout "$REGISTRY_HOST"
|
||||
|
||||
- name: Report status SUCCESS
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && success()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
CONTAINER_URL=""
|
||||
if [ -n "${DOCKER_UI_URL:-}" ] && [ -n "${NEXT_VERSION:-}" ]; then
|
||||
CONTAINER_URL="${DOCKER_UI_URL}/${NEXT_VERSION}"
|
||||
fi
|
||||
bash scripts/report-status.sh success "Docker push $NEXT_VERSION OK" ci-docker-push "" "$CONTAINER_URL"
|
||||
|
||||
- name: Report status FAILURE
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && failure()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
bash scripts/report-status.sh failure "Docker push $NEXT_VERSION FAILED" ci-docker-push
|
||||
|
||||
tag-commit:
|
||||
needs: [check, push]
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check, push]
|
||||
if: needs.check.outputs.artifact_exists != 'true'
|
||||
steps:
|
||||
- name: Create git tag
|
||||
run: |
|
||||
VERSION="${{ needs.check.outputs.version }}"
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||
"$GITEA_API_URL/api/v1/repos/$GITHUB_REPOSITORY/tags" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"tag_name\": \"$VERSION\",
|
||||
\"message\": \"Build #$GITHUB_RUN_NUMBER\",
|
||||
\"target\": \"$GITHUB_SHA\"
|
||||
}")
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
if [ "$HTTP_CODE" = "201" ]; then
|
||||
echo "Tag $VERSION created"
|
||||
elif [ "$HTTP_CODE" = "409" ]; then
|
||||
echo "Tag $VERSION already exists (parallel build won), skipping"
|
||||
else
|
||||
echo "Failed to create tag: HTTP $HTTP_CODE"
|
||||
- name: Download build env
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-context
|
||||
path: /tmp/build-ctx
|
||||
|
||||
- name: Verify Push Status
|
||||
id: gatekeeper
|
||||
run: |
|
||||
PUSH_RESULT="${{ needs.push.result }}"
|
||||
source /tmp/build-ctx/build.env
|
||||
if [ "$PUSH_RESULT" != "success" ]; then
|
||||
echo "gitea-ci-library - Push vaihe epäonnistui. Keskeytetään." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "${ARTIFACT_EXISTS}" = "true" ]; then
|
||||
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Set Gitea status to PENDING
|
||||
if: steps.gatekeeper.outputs.skip == 'false'
|
||||
run: |
|
||||
echo "===== gitea-ci-library - Create Tag | begin ====="
|
||||
bash scripts/report-status.sh pending "Creating tag..." ci-docker-tag
|
||||
|
||||
- name: Create git tag
|
||||
if: steps.gatekeeper.outputs.skip == 'false'
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
REPO: ${{ github.repository }}
|
||||
SERVER_URL: ${{ gitea.server_url }}
|
||||
RUN_NUMBER: ${{ github.run_number }}
|
||||
SHA: ${{ github.sha }}
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||
"$SERVER_URL/api/v1/repos/$REPO/tags" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\": \"$NEXT_VERSION\", \"message\": \"Build #$RUN_NUMBER\", \"target\": \"$SHA\"}")
|
||||
|
||||
if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "409" ]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Report status SUCCESS
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && success()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
bash scripts/report-status.sh success "Tag $NEXT_VERSION OK" ci-docker-tag
|
||||
|
||||
- name: Report status FAILURE
|
||||
if: steps.gatekeeper.outputs.skip == 'false' && failure()
|
||||
run: |
|
||||
source /tmp/build-ctx/build.env
|
||||
bash scripts/report-status.sh failure "Tag $NEXT_VERSION FAILED" ci-docker-tag
|
||||
|
||||
+12
-12
@@ -11,22 +11,22 @@ jobs:
|
||||
with:
|
||||
config_path: .gitea/workflows/gitea-env.conf
|
||||
|
||||
feature:
|
||||
name: Quality Gate
|
||||
if: github.ref != 'refs/heads/main'
|
||||
needs: [load-config]
|
||||
uses: niko/gitea-ci-library/.gitea/workflows/quality-gate.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
env_json: ${{ needs.load-config.outputs.env_json }}
|
||||
bats-image: bats/bats:latest
|
||||
cucumber-node-image: node:22
|
||||
# feature:
|
||||
# name: Quality Gate
|
||||
# if: github.ref != 'refs/heads/main'
|
||||
# needs: [load-config]
|
||||
# uses: niko/gitea-ci-library/.gitea/workflows/quality-gate.yml@main
|
||||
# secrets: inherit
|
||||
# with:
|
||||
# env_json: ${{ needs.load-config.outputs.env_json }}
|
||||
# bats-image: bats/bats:latest
|
||||
# cucumber-node-image: node:22
|
||||
|
||||
main:
|
||||
name: Build & Push Artifact
|
||||
if: github.ref == 'refs/heads/main'
|
||||
# if: github.ref == 'refs/heads/main' # FIXME: väliaikainen — ajetaan tässä haarassa
|
||||
needs: [load-config]
|
||||
uses: niko/gitea-ci-library/.gitea/workflows/build_publish-artifact.yml@main
|
||||
uses: niko/gitea-ci-library/.gitea/workflows/build_publish-artifact.yml@feature/docker-kuntoon
|
||||
secrets: inherit
|
||||
with:
|
||||
env_json: ${{ needs.load-config.outputs.env_json }}
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
GITEA_API_URL=https://gitea.app.keskikuja.site
|
||||
GIT_PAGES_URL=https://ci-reports.helm-dev.keskikuja.site
|
||||
DOCKER_REGISTRY=gitea.app.keskikuja.site/niko
|
||||
DOCKER_IMAGE_NAME=gitea-ci-library-test-image
|
||||
DOCKER_UI_URL=https://gitea.app.keskikuja.site/niko/-/packages/container/gitea-ci-library-test-image
|
||||
|
||||
@@ -33,9 +33,23 @@ jobs:
|
||||
repository: niko/gitea-ci-library
|
||||
path: .ci
|
||||
|
||||
- name: Pending
|
||||
run: bash .ci/scripts/report-status.sh pending "Validating CI config..." ci-validate
|
||||
|
||||
- name: Validate CI config
|
||||
id: validate
|
||||
run: bash .ci/scripts/ci-validate.sh
|
||||
|
||||
- name: Report status
|
||||
if: always()
|
||||
run: |
|
||||
if [ "${{ steps.validate.outcome }}" = "success" ]; then
|
||||
bash .ci/scripts/report-status.sh success "CI config valid" ci-validate
|
||||
else
|
||||
bash .ci/scripts/report-status.sh failure "CI validation FAILED" ci-validate
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bats:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -45,6 +59,9 @@ jobs:
|
||||
repository: niko/gitea-ci-library
|
||||
path: .ci
|
||||
|
||||
- name: Pending
|
||||
run: bash .ci/scripts/report-status.sh pending "Running Bats tests..." ci-bats
|
||||
|
||||
- name: Run bats tests
|
||||
id: bats-tests
|
||||
shell: bash
|
||||
@@ -69,11 +86,11 @@ jobs:
|
||||
if: always()
|
||||
run: bash .ci/scripts/publish-git-pages.sh bats
|
||||
|
||||
- name: Set bats commit status
|
||||
- name: Report status
|
||||
if: always()
|
||||
run: |
|
||||
if [ "${BATS_EXIT}" = "0" ]; then
|
||||
bash .ci/scripts/report-status.sh success "Bats tests" ci-bats bats
|
||||
bash .ci/scripts/report-status.sh success "Bats tests OK" ci-bats bats
|
||||
else
|
||||
bash .ci/scripts/report-status.sh failure "Bats tests FAILED" ci-bats bats
|
||||
fi
|
||||
@@ -89,6 +106,9 @@ jobs:
|
||||
repository: niko/gitea-ci-library
|
||||
path: .ci
|
||||
|
||||
- name: Pending
|
||||
run: bash .ci/scripts/report-status.sh pending "Running Cucumber tests..." ci-cucumber
|
||||
|
||||
- name: Run cucumber tests
|
||||
id: cucumber-tests
|
||||
shell: bash
|
||||
@@ -101,21 +121,30 @@ jobs:
|
||||
--format json:"reports/${GITHUB_SHA:0:8}/cucumber/report.json" \
|
||||
--format html:"reports/${GITHUB_SHA:0:8}/cucumber/index.html" 2>&1
|
||||
CUCUMBER_EXIT=$?
|
||||
|
||||
STATE="success"
|
||||
[ "${CUCUMBER_EXIT}" != "0" ] && STATE="failure"
|
||||
if [ -f "reports/${GITHUB_SHA:0:8}/cucumber/index.html" ]; then
|
||||
bash .ci/scripts/report-status.sh "${STATE}" "Cucumber tests" ci-cucumber cucumber
|
||||
else
|
||||
bash .ci/scripts/report-status.sh "${STATE}" "Cucumber tests" ci-cucumber
|
||||
fi
|
||||
|
||||
echo "CUCUMBER_EXIT=${CUCUMBER_EXIT}" >> "${GITHUB_ENV}"
|
||||
exit ${CUCUMBER_EXIT}
|
||||
|
||||
- name: Publish cucumber reports
|
||||
if: always()
|
||||
run: bash .ci/scripts/publish-git-pages.sh cucumber
|
||||
|
||||
- name: Report status
|
||||
if: always()
|
||||
run: |
|
||||
if [ "${CUCUMBER_EXIT}" = "0" ]; then
|
||||
if [ -f "reports/${GITHUB_SHA:0:8}/cucumber/index.html" ]; then
|
||||
bash .ci/scripts/report-status.sh success "Cucumber tests OK" ci-cucumber cucumber
|
||||
else
|
||||
bash .ci/scripts/report-status.sh success "Cucumber tests OK" ci-cucumber
|
||||
fi
|
||||
else
|
||||
if [ -f "reports/${GITHUB_SHA:0:8}/cucumber/index.html" ]; then
|
||||
bash .ci/scripts/report-status.sh failure "Cucumber tests FAILED" ci-cucumber cucumber
|
||||
else
|
||||
bash .ci/scripts/report-status.sh failure "Cucumber tests FAILED" ci-cucumber
|
||||
fi
|
||||
fi
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [bats, cucumber]
|
||||
@@ -126,8 +155,19 @@ jobs:
|
||||
repository: niko/gitea-ci-library
|
||||
path: .ci
|
||||
|
||||
- name: Pending
|
||||
run: bash .ci/scripts/report-status.sh pending "Generating report index..." ci-build
|
||||
|
||||
- name: Generate report index
|
||||
id: report-index
|
||||
run: bash .ci/.gitea/scripts/generate-report-index.sh
|
||||
|
||||
- name: Set build commit status
|
||||
run: bash .ci/scripts/report-status.sh success "Build complete" ci-build
|
||||
- name: Report status
|
||||
if: always()
|
||||
run: |
|
||||
if [ "${{ steps.report-index.outcome }}" = "success" ]; then
|
||||
bash .ci/scripts/report-status.sh success "Build complete" ci-build
|
||||
else
|
||||
bash .ci/scripts/report-status.sh failure "Build FAILED" ci-build
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -29,11 +29,11 @@ Polku löytyy repostasi:
|
||||
git remote get-url origin
|
||||
# → ssh://git@gitea.app.keskikuja.site:30009/niko/gitea-ci-library.git
|
||||
# owner = niko, repo = gitea-ci-library
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
Consumerin `ci.yml`:
|
||||
|
||||
```yaml
|
||||
```yaml
|
||||
jobs:
|
||||
call-engine:
|
||||
uses: niko/gitea-ci-library/.gitea/workflows/build-feature.yml@v1
|
||||
@@ -102,34 +102,56 @@ Act runner suorittaa Gitea Actions workflowt. **IaC-lähde:** alla oleva Helm-sn
|
||||
klusterin totuus — muutokset vain snippetiin, sitten `helm upgrade --install` (ei käsin muokattuja
|
||||
arvoja klusterissa).
|
||||
|
||||
> HUOM! Gitea ei ole vielä kunnolla stabiilissa tilassa, ja chart default dind sekä runner versiot ovat tätä tehdessä olleet bugiset. Niistä on olemassa uudemmat versiot, mutta eivät ole chartissa. Tätyy seurata ja päivittää tarpeen tulle.
|
||||
|
||||
Asennus Kubernetes-klusteriin Helm chartilla:
|
||||
|
||||
### 1. Rekisteröintitoken
|
||||
### 1. Rekisteröi token
|
||||
|
||||
Hae token Giteasta:
|
||||
- **Organization-taso:** Org → Settings → Actions → Runners → Create new runner
|
||||
- **Globaali (site admin):** Site Admin → Actions → Runners → Create new runner
|
||||
|
||||
### 2. Asenna runner
|
||||
### 2. variables
|
||||
|
||||
```bash
|
||||
GITEA_URL="https://<gitea-server-url>"
|
||||
GITEA_ACTIONS_TOKEN="<registration-token>"
|
||||
GITEA_ACTIONS_NAMESPACE="gitea-actions"
|
||||
```
|
||||
|
||||
helm repo add gitea https://dl.gitea.com/charts
|
||||
helm repo update
|
||||
### 3. Tee secret vain init install yhteydessä
|
||||
|
||||
```bash
|
||||
kubectl create secret generic act-runner-token \
|
||||
--from-literal=token="$GITEA_ACTIONS_TOKEN" \
|
||||
--namespace "$GITEA_ACTIONS_NAMESPACE" \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
```
|
||||
|
||||
### 4. Helm install / upgrade
|
||||
|
||||
Menee samalla komennolla.
|
||||
|
||||
> Muista asettaa variables ennen ajoa.
|
||||
|
||||
Päivittää olemassa olevan installaation, käyttää olemassa olevaa secret
|
||||
ja sitä kautta Gitea ei tarvitse päivityksessä mitään temppuja.
|
||||
|
||||
Päivityksen jälkeen muista tappaa pod (käynnistyy automaattisesti uudelleen), että lataa varmasti kaikki uudesta. Sillä ConfigMap tms eivät lataudu
|
||||
mikäli pod jatkaa ajamista.
|
||||
|
||||
```bash
|
||||
helm repo add gitea https://dl.gitea.com/charts
|
||||
helm repo update
|
||||
|
||||
helm upgrade --install act-runner gitea/actions \
|
||||
--set enabled=true \
|
||||
--set giteaRootURL="$GITEA_URL" \
|
||||
--set existingSecret=act-runner-token \
|
||||
--set existingSecretKey=token \
|
||||
--set statefulset.runner.tag=1.0.8 \
|
||||
--set statefulset.dind.tag=29.5.2-dind \
|
||||
--set-string 'statefulset.runner.config=log:
|
||||
level: info
|
||||
|
||||
@@ -16,24 +16,41 @@ curl_with_host() {
|
||||
declare -A BRANCH_CACHE
|
||||
branch_exists() {
|
||||
local owner="$1" repo="$2" branch="$3" key="${owner}/${repo}/${branch}"
|
||||
local status
|
||||
|
||||
local status attempt
|
||||
|
||||
[ -z "$GITEA_API_URL" ] && return 0
|
||||
[ -z "$GITEA_TOKEN" ] && return 0
|
||||
|
||||
|
||||
if [ "${BRANCH_CACHE[$key]:-}" = "1" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
status=$(curl -sS -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_API_URL}/api/v1/repos/${owner}/${repo}/branches/${branch}" 2>/dev/null || echo "000")
|
||||
|
||||
if [ "$status" = "200" ]; then
|
||||
BRANCH_CACHE[$key]=1
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
|
||||
# Retry up to 2 times on API errors (hardcoded)
|
||||
for attempt in 1 2 3; do
|
||||
status=$(curl -sS -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_API_URL}/api/v1/repos/${owner}/${repo}/branches/${branch}" 2>/dev/null || echo "000")
|
||||
|
||||
if [ "$status" = "200" ]; then
|
||||
BRANCH_CACHE[$key]=1
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$status" = "404" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# API error - retry if not last attempt
|
||||
if [ "$attempt" -lt 3 ]; then
|
||||
sleep 10
|
||||
continue
|
||||
fi
|
||||
done
|
||||
|
||||
# All retries failed - keep report (fail-safe)
|
||||
echo " WARN: Gitea API error for ${owner}/${repo}/${branch} (status ${status}) after 3 attempts - KEEPING report"
|
||||
BRANCH_CACHE[$key]=1
|
||||
return 0
|
||||
}
|
||||
|
||||
default_max_age=$(jq -r '.branches.default.maxAgeDays // 90' "$CONFIG")
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
# Docker Registry Setup
|
||||
|
||||
Pipeline rakentaa Docker-kontin ja pushee sen haluttuun registryyn.
|
||||
|
||||
---
|
||||
|
||||
## 1. Konfiguroi `gitea-env.conf`
|
||||
|
||||
```
|
||||
# DOCKER_REGISTRY on muotoa: registry.example.com/org
|
||||
#
|
||||
# host+org: registry.example.com/org
|
||||
#
|
||||
# Pipeline rakentaa kuvan: ${DOCKER_REGISTRY}/${DOCKER_IMAGE_NAME}:${VERSION}
|
||||
|
||||
DOCKER_REGISTRY=gitea.app.keskikuja.site/niko # PAKOLLINEN — tyhjä ei käy
|
||||
DOCKER_IMAGE_NAME=gitea-ci-library-test-image # PAKOLLINEN — pelkkä kuvan nimi
|
||||
DOCKER_UI_URL= # valinnainen — tarkista Giteasta kontin oma UI-osoite ja laita se tähän ilman versiota. Workflow liittää perään /VERSION
|
||||
```
|
||||
|
||||
| Kenttä | Pakollinen | Kuvaus |
|
||||
|---|---|---|
|
||||
| `DOCKER_REGISTRY` | **kyllä** | Registry + mahdollinen organisaatio. **Tyhjä pysäyttää workflow'n.** |
|
||||
| `DOCKER_IMAGE_NAME` | **kyllä** | Pelkkä kuvan nimi. |
|
||||
| `DOCKER_UI_URL` | ei | Base-URL kontin UI-sivulle (ilman versiota). Osoite riippuu onko kontti linkitetty repoon vai ei — tarkista Giteasta. Workflow liittää perään `/VERSION`. |
|
||||
|
||||
**Koko image-ref = `${DOCKER_REGISTRY}/${DOCKER_IMAGE_NAME}:${VERSION}`**
|
||||
Esim. `gitea.app.keskikuja.site/niko/gitea-ci-library-test-image:0.1.0`
|
||||
|
||||
---
|
||||
|
||||
## 2. Luo PAT (Personal Access Token) Giteassa
|
||||
|
||||
**Gitea → oma profiili (oikea yläkulma) → Settings → Applications → Manage Access Tokens → Generate New Token**
|
||||
|
||||
Valitse scope:
|
||||
|
||||
| Scope | Pääsy |
|
||||
|---|---|
|
||||
| `package` | **Read and Write** |
|
||||
|
||||
> Tämä token toimii salasanana `docker login` -komennossa. Muut scopet (kuten `repository`) eivät riitä — konttirekisteri vaatii nimenomaan `package`-scopen.
|
||||
|
||||
Tokenin arvo näytetään **vain kerran** luomisen yhteydessä. Kopioi se talteen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Tallenna PAT repositoryn Secretsiin
|
||||
|
||||
Nämä ovat kaksi eri paikkaa:
|
||||
- **Access Tokenit** (User Settings) = missä luot tokenin
|
||||
- **Repository Secrets** (Repository Settings) = minne talletat sen workflow'n käyttöön
|
||||
|
||||
**Repository → Settings → Actions → Secrets → Add new secret**
|
||||
|
||||
| Secret | Arvo |
|
||||
|---|---|
|
||||
| `DOCKER_PASSWORD` | Edellisessä vaiheessa luotu PAT |
|
||||
|
||||
`DOCKER_USERNAME`-secretiä **ei tarvita**. Workflow käyttää automaattisesti `${{ github.actor }}` (workflowin käynnistäjä).
|
||||
|
||||
Jos registry vaatii eri käyttäjätunnuksen kuin `github.actor` (esim. Artifactory, Docker Hub), lisää myös:
|
||||
|
||||
| Secret | Arvo |
|
||||
|---|---|
|
||||
| `DOCKER_USERNAME` | Registryn käyttäjätunnus |
|
||||
|
||||
---
|
||||
|
||||
## 4. Tarkistuslista ennen ajoa
|
||||
|
||||
- [ ] `DOCKER_REGISTRY` asetettu `gitea-env.conf`issa
|
||||
- [ ] `DOCKER_IMAGE_NAME` asetettu `gitea-env.conf`issa
|
||||
- [ ] PAT luotu Giteassa scopella `package` Read and Write
|
||||
- [ ] `DOCKER_PASSWORD`-secret tallennettu repositoryn Secretsiin (se PAT)
|
||||
- [ ] (tarvittaessa) `DOCKER_USERNAME`-secret — oletus `github.actor`
|
||||
|
||||
---
|
||||
|
||||
## 5. Esimerkkejä eri polkurakenteista
|
||||
|
||||
### 5a. Pelkkä hosti — Artifactory
|
||||
|
||||
```
|
||||
DOCKER_REGISTRY=ngdo-docker.artifactorypro.shared.pub.tds.tieto.com
|
||||
DOCKER_IMAGE_NAME=microservice-temperature-store
|
||||
DOCKER_UI_URL=https://artifactorypro.shared.pub.tds.tieto.com/ui/repos/tree/General/ngdo-docker.artifactorypro.shared.pub.tds.tieto.com/microservice-temperature-store
|
||||
```
|
||||
|
||||
- Kontti: `ngdo-docker.../microservice-temperature-store:0.1.0`
|
||||
- Secret `DOCKER_USERNAME` = service account -tunnus
|
||||
- Secret `DOCKER_PASSWORD` = API-token
|
||||
|
||||
### 5b. Hosti + org — Gitea user-taso
|
||||
|
||||
```
|
||||
DOCKER_REGISTRY=gitea.app.keskikuja.site/niko
|
||||
DOCKER_IMAGE_NAME=gitea-ci-library-test-image
|
||||
DOCKER_UI_URL= # tarkista Giteasta kontin UI-osoite
|
||||
```
|
||||
|
||||
- Kontti: `gitea.app.keskikuja.site/niko/gitea-ci-library-test-image:0.1.0`
|
||||
- Paketti käyttäjän `niko` alla. Linkitys repoon tehdään Gitean UI:sta: paketin sivulta (Package → Settings) → linkitä repositoryyn.
|
||||
|
||||
```
|
||||
DOCKER_REGISTRY=docker.io/library
|
||||
DOCKER_IMAGE_NAME=oma-kuva
|
||||
DOCKER_UI_URL=https://hub.docker.com/r/library/oma-kuva
|
||||
```
|
||||
|
||||
- Secret `DOCKER_USERNAME` = Docker Hub -käyttäjä
|
||||
- Secret `DOCKER_PASSWORD` = Access Token (ei salasana)
|
||||
@@ -1,17 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# https://docs.gitea.com/api/next/#tag/repository/operation/repoCreateStatus
|
||||
|
||||
STATE="${1:-}"
|
||||
DESCRIPTION="${2:-}"
|
||||
KEY="${3:-commit-${GITHUB_SHA:0:8}}"
|
||||
SUITE="${4:-}"
|
||||
CUSTOM_URL="${5:-}"
|
||||
|
||||
[ -z "$STATE" ] && echo "ERROR: state argument is required" >&2 && exit 1
|
||||
[ -z "$DESCRIPTION" ] && echo "ERROR: description argument is required" >&2 && exit 1
|
||||
[ -z "${GITEA_API_URL:-}" ] && echo "ERROR: GITEA_API_URL is not set" >&2 && exit 1
|
||||
[ -z "${GITEA_TOKEN:-}" ] && echo "ERROR: GITEA_TOKEN is not set" >&2 && exit 1
|
||||
|
||||
if [ -n "$SUITE" ]; then
|
||||
if [ -n "$CUSTOM_URL" ]; then
|
||||
URL="$CUSTOM_URL"
|
||||
elif [ -n "$SUITE" ]; then
|
||||
SUITE="${SUITE%/}/"
|
||||
URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${GITHUB_SHA:0:8}/${SUITE}"
|
||||
else
|
||||
@@ -28,15 +33,15 @@ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-X POST "$GITEA_API_URL/api/v1/repos/$REPO/statuses/$COMMIT" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"state\":\"$STATE\",\"target_url\":\"$URL\",\"description\":\"$DESCRIPTION\",\"context\":\"$KEY\"}")
|
||||
-d "{\"state\":\"$STATE\",\"target_url\":\"$URL\",\"description\":\"$DESCRIPTION\",\"context\":\"$KEY\"}" || true)
|
||||
|
||||
if [ "$HTTP_CODE" = "201" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$HTTP_CODE" ]; then
|
||||
echo "ERROR: Failed to connect to Gitea API at $GITEA_API_URL" >&2
|
||||
if [ -z "$HTTP_CODE" ] || [ "$HTTP_CODE" = "000" ]; then
|
||||
echo "gitea-ci-library - ERROR: Failed to connect to Gitea API at $GITEA_API_URL" >&2
|
||||
else
|
||||
echo "ERROR: API returned HTTP $HTTP_CODE" >&2
|
||||
echo "gitea-ci-library - ERROR: gitea-ci-library, API returned HTTP $HTTP_CODE" >&2
|
||||
fi
|
||||
exit 1
|
||||
|
||||
@@ -6,10 +6,15 @@ const PROJECT_ROOT = path.resolve(__dirname, '..', '..', '..');
|
||||
const MOCK_SCRIPT = path.join(PROJECT_ROOT, 'tests', 'helpers', 'mock-api.sh');
|
||||
|
||||
Before({ tags: '@mock' }, function () {
|
||||
execSync(`bash -c 'source "${MOCK_SCRIPT}" && mock_start'`, {
|
||||
const out = execSync(`bash -c 'source "${MOCK_SCRIPT}" && mock_start && sleep 0.3 && curl -s -o /dev/null -w "%{http_code}" --max-time 3 http://localhost:18080/api/v1/repos/health/check'`, {
|
||||
cwd: PROJECT_ROOT,
|
||||
stdio: 'ignore',
|
||||
encoding: 'utf-8',
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
});
|
||||
const trimmed = out.trim();
|
||||
if (!trimmed.startsWith('2') && !trimmed.startsWith('4')) {
|
||||
throw new Error(`Mock server failed to start (HTTP ${trimmed})`);
|
||||
}
|
||||
});
|
||||
|
||||
After({ tags: '@mock' }, function () {
|
||||
|
||||
Reference in New Issue
Block a user