diff --git a/build-push-notify/action.yml b/build-push-notify/action.yml index 9ca83c3..fbd75f6 100644 --- a/build-push-notify/action.yml +++ b/build-push-notify/action.yml @@ -44,45 +44,93 @@ inputs: runs: using: 'composite' steps: - - name: Install curl and jq + - name: Install curl, jq, buildah and qemu-user-static run: | - if which curl > /dev/null && which jq > /dev/null; then - echo "curl and jq are already installed" - else - sudo apt-get update && sudo apt-get install -y curl jq + pkgs="" + which curl > /dev/null || pkgs="$pkgs curl" + which jq > /dev/null || pkgs="$pkgs jq" + which buildah > /dev/null || pkgs="$pkgs buildah" + dpkg -s qemu-user-static > /dev/null 2>&1 || pkgs="$pkgs qemu-user-static" + if [ -n "$pkgs" ]; then + sudo apt-get update && sudo apt-get install -y $pkgs fi shell: bash + - name: Configure rootless buildah + run: | + grep -q "runner:" /etc/subuid 2>/dev/null || echo "runner:100000:65536" | sudo tee -a /etc/subuid + grep -q "runner:" /etc/subgid 2>/dev/null || echo "runner:100000:65536" | sudo tee -a /etc/subgid + shell: bash - name: Checkout - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Login to registry - uses: docker/login-action@v3 - with: - registry: ${{ inputs.REGISTRY_URL }} - username: ${{ inputs.REGISTRY_USERNAME }} - password: ${{ inputs.REGISTRY_PASSWORD }} + env: + REGISTRY_URL: ${{ inputs.REGISTRY_URL }} + REGISTRY_USERNAME: ${{ inputs.REGISTRY_USERNAME }} + REGISTRY_PASSWORD: ${{ inputs.REGISTRY_PASSWORD }} + BUILDAH_ISOLATION: chroot + run: | + echo "$REGISTRY_PASSWORD" | buildah login -u "$REGISTRY_USERNAME" --password-stdin "$REGISTRY_URL" + shell: bash - name: Run pre-build commands if: ${{ inputs.PRE_BUILD_COMMANDS != '' }} env: PRE_BUILD_COMMANDS: ${{ inputs.PRE_BUILD_COMMANDS }} run: | - $PRE_BUILD_COMMANDS + while IFS= read -r cmd; do + [ -n "$cmd" ] && eval "$cmd" + done <<< "$PRE_BUILD_COMMANDS" + shell: bash + - name: Build and push + env: + IMAGE_TAGS: ${{ inputs.IMAGE_TAGS }} + PLATFORMS: ${{ inputs.PLATFORMS }} + CONTEXT: ${{ inputs.CONTEXT }} + DOCKERFILE: ${{ inputs.DOCKERFILE }} + BUILD_ARGS: ${{ inputs.BUILD_ARGS }} + TARGET: ${{ inputs.TARGET }} + run: | + # Assemble --build-arg flags + buildarg_args=() + while IFS= read -r arg; do + [ -n "$arg" ] && buildarg_args+=(--build-arg "$arg") + done <<< "$BUILD_ARGS" + + # Assemble --target flag + target_args=() + [ -n "$TARGET" ] && target_args+=(--target "$TARGET") + + if [[ "$PLATFORMS" == *","* ]]; then + # Multi-platform: build a manifest list, then push to each tag + buildah build \ + --isolation=chroot \ + --manifest local-manifest \ + --platform "$PLATFORMS" \ + -f "$DOCKERFILE" \ + "${buildarg_args[@]}" \ + "${target_args[@]}" \ + "$CONTEXT" + while IFS= read -r tag; do + [ -n "$tag" ] && buildah manifest push --all local-manifest "docker://$tag" + done <<< "$IMAGE_TAGS" + else + # Single platform: build with explicit tags, then push each + tag_args=() + while IFS= read -r tag; do + [ -n "$tag" ] && tag_args+=(-t "$tag") + done <<< "$IMAGE_TAGS" + buildah build \ + --isolation=chroot \ + "${tag_args[@]}" \ + --platform "$PLATFORMS" \ + -f "$DOCKERFILE" \ + "${buildarg_args[@]}" \ + "${target_args[@]}" \ + "$CONTEXT" + while IFS= read -r tag; do + [ -n "$tag" ] && buildah push "$tag" + done <<< "$IMAGE_TAGS" + fi shell: bash - - name: Build - uses: docker/build-push-action@v6.2.0 - with: - context: ${{ inputs.CONTEXT }} - file: ${{ inputs.DOCKERFILE }} - tags: | - ${{ inputs.IMAGE_TAGS }} - platforms: ${{ inputs.PLATFORMS }} - pull: true - push: true - build-args: ${{ inputs.BUILD_ARGS }} - target: ${{ inputs.TARGET }} - name : Send notification on Mattermost if: ${{ inputs.MATTERMOST_WEBHOOK_URL != '' }} env: diff --git a/code-analysis-notify/action.yml b/code-analysis-notify/action.yml index 8c653af..b68c908 100644 --- a/code-analysis-notify/action.yml +++ b/code-analysis-notify/action.yml @@ -32,7 +32,7 @@ runs: fi shell: bash - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Run checks uses: IMIO/code-analysis-action@7969d657a907cb4d3b8e426481ba41a44cb57554 # main as of 2026-03-13 with: diff --git a/helm-release-notify/action.yml b/helm-release-notify/action.yml index 3acacbb..d66c12c 100644 --- a/helm-release-notify/action.yml +++ b/helm-release-notify/action.yml @@ -41,10 +41,10 @@ runs: fi shell: bash - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 0 - - uses: actions/create-github-app-token@v1 + - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 id: app-token with: app-id: ${{ inputs.APP_ID }} diff --git a/helm-test-notify/action.yml b/helm-test-notify/action.yml index cbea9fd..c0cd054 100644 --- a/helm-test-notify/action.yml +++ b/helm-test-notify/action.yml @@ -32,26 +32,26 @@ runs: fi shell: bash - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 0 - name: Set up Helm - uses: azure/setup-helm@v4.2.0 + uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0 with: version: ${{ inputs.HELM_VERSION }} - - uses: actions/setup-python@v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: ${{ inputs.PYTHON_VERSION }} check-latest: true - name: Set up chart-testing - uses: helm/chart-testing-action@v2.6.1 + uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1 - name: Run chart-testing (lint) env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} run: ct lint --chart-dirs . --charts . --target-branch "$DEFAULT_BRANCH" shell: bash - name: Create kind cluster - uses: helm/kind-action@v1.10.0 + uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0 - name: Run chart-testing (install) # run: ct install --chart-dirs . --charts . --target-branch ${{ github.event.repository.default_branch }} # can't use it until https://github.com/helm/chart-testing/issues/310 is resolved diff --git a/k8s-update-tag/action.yml b/k8s-update-tag/action.yml index 38bd89e..6b485d2 100644 --- a/k8s-update-tag/action.yml +++ b/k8s-update-tag/action.yml @@ -29,9 +29,10 @@ runs: shell: bash - name: Install yq run: | - sudo wget https://github.com/mikefarah/yq/releases/download/v4.47.2/yq_linux_amd64 -O /usr/local/bin/yq - echo "1bb99e1019e23de33c7e6afc23e93dad72aad6cf2cb03c797f068ea79814ddb0 /usr/local/bin/yq" | sha256sum -c - sudo chmod +x /usr/local/bin/yq + wget https://github.com/mikefarah/yq/releases/download/v4.47.2/yq_linux_amd64 -O /tmp/yq + echo "1bb99e1019e23de33c7e6afc23e93dad72aad6cf2cb03c797f068ea79814ddb0 /tmp/yq" | sha256sum -c + sudo install -m 0755 /tmp/yq /usr/local/bin/yq + rm /tmp/yq shell: bash - name: Configure Git and repository env: @@ -40,9 +41,12 @@ runs: REPO_URL: ${{ inputs.REPO_URL }} TARGET_BRANCH: ${{ inputs.TARGET_BRANCH }} run: | - git clone "https://${REPO_TOKEN_NAME}:${REPO_ACCESS_TOKEN}@${REPO_URL}" repo + # Store credentials in .netrc to avoid leaking them in git URLs / process listing + printf 'machine %s\nlogin %s\npassword %s\n' "${REPO_URL%%/*}" "$REPO_TOKEN_NAME" "$REPO_ACCESS_TOKEN" > ~/.netrc + chmod 600 ~/.netrc + trap 'rm -f ~/.netrc' EXIT + git clone "https://${REPO_URL}" repo cd repo - # Remove credentials from remote URL to avoid leaking them via git remote -v git remote set-url origin "https://${REPO_URL}" git config --global user.email "github-ci@imio.be" git config --global user.name "GitHub Actions CI" @@ -53,9 +57,6 @@ runs: VALUES_FILE_PATH: ${{ inputs.VALUES_FILE_PATH }} TAG: ${{ inputs.TAG }} TARGET_BRANCH: ${{ inputs.TARGET_BRANCH }} - REPO_TOKEN_NAME: ${{ inputs.REPO_TOKEN_NAME }} - REPO_ACCESS_TOKEN: ${{ inputs.REPO_ACCESS_TOKEN }} - REPO_URL: ${{ inputs.REPO_URL }} run: | cd repo # Update the tag in the values file @@ -64,5 +65,11 @@ runs: # Add and commit changes git add "$VALUES_FILE_PATH" git commit --allow-empty -m "CI Automated Deploy of $VALUES_FILE_PATH with tag $TAG" - git push "https://${REPO_TOKEN_NAME}:${REPO_ACCESS_TOKEN}@${REPO_URL}" "HEAD:${TARGET_BRANCH}" + git push origin "HEAD:${TARGET_BRANCH}" + # Clear stored credentials + rm -f ~/.netrc + shell: bash + - name: Clean up credentials + if: always() + run: rm -f ~/.netrc shell: bash diff --git a/plone-package-test-notify/action.yml b/plone-package-test-notify/action.yml index 8fc5138..98f4ae6 100644 --- a/plone-package-test-notify/action.yml +++ b/plone-package-test-notify/action.yml @@ -46,17 +46,17 @@ runs: fi shell: bash - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Cache eggs if: ${{ inputs.CACHE_KEY != '' }} - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 env: cache-name: cache-eggs with: path: ./eggs key: ${{ inputs.CACHE_KEY }} - name: Install uv and set the python version - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0 with: python-version: ${{ inputs.PYTHON_VERSION }} version: ${{ inputs.UV_VERSION }} @@ -70,7 +70,7 @@ runs: errors=0 for command in "${commands[@]}"; do echo "Running command: $command" - $command || errors=$((errors + 1)) + bash -c "$command" || errors=$((errors + 1)) done [ "$errors" -eq 0 ] - name: Run buildout @@ -80,13 +80,16 @@ runs: BUILDOUT_CONFIG_FILE: ${{ inputs.BUILDOUT_CONFIG_FILE }} shell: bash run: | - $BUILDOUT_COMMAND $BUILDOUT_OPTIONS -c "$BUILDOUT_CONFIG_FILE" buildout:eggs-directory=./eggs + read -ra buildout_cmd <<< "$BUILDOUT_COMMAND" + read -ra buildout_opts <<< "$BUILDOUT_OPTIONS" + "${buildout_cmd[@]}" "${buildout_opts[@]}" -c "$BUILDOUT_CONFIG_FILE" buildout:eggs-directory=./eggs - name: Run tests env: TEST_COMMAND: ${{ inputs.TEST_COMMAND }} shell: bash run: | - eval "$TEST_COMMAND" + eval "cmd=($TEST_COMMAND)" + "${cmd[@]}" - name : Send notification on Mattermost if: ${{ inputs.MATTERMOST_WEBHOOK_URL != '' }} env: diff --git a/plone-theme-build-push-notify/action.yml b/plone-theme-build-push-notify/action.yml index 5633b9f..d574a7a 100644 --- a/plone-theme-build-push-notify/action.yml +++ b/plone-theme-build-push-notify/action.yml @@ -54,7 +54,7 @@ runs: THEME_PATH: ${{ inputs.THEME_PATH }} ACTION_PATH: ${{ github.action_path }} run: | - python3 "$ACTION_PATH/theme_uploader.py" "$PLONE_URL" "$PLONE_USERNAME" "$PLONE_PASSWORD" "$THEME_PATH" theme.zip + python3 "$ACTION_PATH/theme_uploader.py" "$PLONE_URL" "$THEME_PATH" theme.zip shell: bash - name : Send notification on Mattermost if: ${{ inputs.MATTERMOST_WEBHOOK_URL != '' }} diff --git a/plone-theme-build-push-notify/theme_uploader.py b/plone-theme-build-push-notify/theme_uploader.py index fc5a547..664b172 100644 --- a/plone-theme-build-push-notify/theme_uploader.py +++ b/plone-theme-build-push-notify/theme_uploader.py @@ -5,20 +5,25 @@ This script is used to upload a theme to a Plone instance. Usage: - python theme_uploader.py INSTANCE_URL USERNAME PASSWORD THEME_LOCATION + python theme_uploader.py INSTANCE_URL THEME_PATH THEME_FILENAME + +Environment variables: + PLONE_USERNAME Plone instance username + PLONE_PASSWORD Plone instance password """ from bs4 import BeautifulSoup +import os import requests import requests.cookies import sys INSTANCE_URL = sys.argv[1] -USERNAME = sys.argv[2] -PASSWORD = sys.argv[3] -THEME_PATH = sys.argv[4] -THEME_FILENAME = sys.argv[5] +USERNAME = os.environ["PLONE_USERNAME"] +PASSWORD = os.environ["PLONE_PASSWORD"] +THEME_PATH = sys.argv[2] +THEME_FILENAME = sys.argv[3] def authenticate( @@ -69,7 +74,7 @@ def main(): session = requests.Session() print("Authenticating to Plone instance...") response = authenticate(session, INSTANCE_URL, USERNAME, PASSWORD) - if "__ac=deleted" in response.headers["set-cookie"]: + if "__ac=deleted" in response.headers.get("set-cookie", ""): print("Authentication failed") sys.exit(1) print("Getting token...") diff --git a/repository-dispatch-notify/action.yml b/repository-dispatch-notify/action.yml index 45dd639..453e19b 100644 --- a/repository-dispatch-notify/action.yml +++ b/repository-dispatch-notify/action.yml @@ -43,7 +43,7 @@ runs: sudo apt-get update && sudo apt-get install -y jq fi shell: bash - - uses: actions/create-github-app-token@v1 + - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 id: app-token with: app-id: ${{ inputs.APP_ID }} @@ -70,13 +70,13 @@ runs: shell: bash - name : Send notification on Mattermost if: ${{ inputs.MATTERMOST_WEBHOOK_URL != '' }} - uses: IMIO/gha/mattermost-notify@v4 + uses: IMIO/gha/mattermost-notify@ec02349a0f486af868fc78489425e65e3b3e0c23 # v6.1.0 with: MATTERMOST_WEBHOOK_URL: ${{ inputs.MATTERMOST_WEBHOOK_URL }} MESSAGE: "Repository dispatch event triggered on repository ${{ inputs.REPOSITORY }}" - name : Send failure notification on Mattermost if: ${{ failure() && inputs.MATTERMOST_WEBHOOK_URL != '' }} - uses: IMIO/gha/mattermost-notify@v4 + uses: IMIO/gha/mattermost-notify@ec02349a0f486af868fc78489425e65e3b3e0c23 # v6.1.0 with: MATTERMOST_WEBHOOK_URL: ${{ inputs.MATTERMOST_WEBHOOK_URL }} MESSAGE: "An error has been encountered while dispatching the event on repository ${{ inputs.REPOSITORY }}" diff --git a/rundeck-notify/action.yml b/rundeck-notify/action.yml index 4edfa5f..1ba0c48 100644 --- a/rundeck-notify/action.yml +++ b/rundeck-notify/action.yml @@ -37,7 +37,9 @@ runs: RUNDECK_PARAMETERS: ${{ inputs.RUNDECK_PARAMETERS }} run: | params=() - eval "params=($RUNDECK_PARAMETERS)" + if [ -n "$RUNDECK_PARAMETERS" ]; then + mapfile -t params <<< "$RUNDECK_PARAMETERS" + fi curl --fail-with-body "${params[@]}" -H "X-Rundeck-Auth-Token: $RUNDECK_TOKEN" "$RUNDECK_URL/api/18/job/$RUNDECK_JOB_ID/run/" -o rundeck-response.json echo "JOB_NAME=$(jq -r .job.name rundeck-response.json)" >> "$GITHUB_OUTPUT" echo "JOB_EXECUTION_PERMALINK=$(jq -r .permalink rundeck-response.json)" >> "$GITHUB_OUTPUT" diff --git a/tag-notify/action.yml b/tag-notify/action.yml index 22f1f42..f09d9c5 100644 --- a/tag-notify/action.yml +++ b/tag-notify/action.yml @@ -27,32 +27,39 @@ inputs: runs: using: 'composite' steps: - - name: Install curl and jq + - name: Install curl, jq and buildah run: | - if which curl > /dev/null && which jq > /dev/null; then - echo "curl and jq are already installed" - else - sudo apt-get update && sudo apt-get install -y curl jq + pkgs="" + which curl > /dev/null || pkgs="$pkgs curl" + which jq > /dev/null || pkgs="$pkgs jq" + which buildah > /dev/null || pkgs="$pkgs buildah" + if [ -n "$pkgs" ]; then + sudo apt-get update && sudo apt-get install -y $pkgs fi shell: bash + - name: Configure rootless buildah + run: | + grep -q "runner:" /etc/subuid 2>/dev/null || echo "runner:100000:65536" | sudo tee -a /etc/subuid + grep -q "runner:" /etc/subgid 2>/dev/null || echo "runner:100000:65536" | sudo tee -a /etc/subgid + shell: bash - name: Checkout - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Login to registry - uses: docker/login-action@v3 - with: - registry: ${{ inputs.REGISTRY_URL }} - username: ${{ inputs.REGISTRY_USERNAME }} - password: ${{ inputs.REGISTRY_PASSWORD }} + env: + REGISTRY_URL: ${{ inputs.REGISTRY_URL }} + REGISTRY_USERNAME: ${{ inputs.REGISTRY_USERNAME }} + REGISTRY_PASSWORD: ${{ inputs.REGISTRY_PASSWORD }} + BUILDAH_ISOLATION: chroot + run: | + echo "$REGISTRY_PASSWORD" | buildah login -u "$REGISTRY_USERNAME" --password-stdin "$REGISTRY_URL" + shell: bash - name: Download image env: REGISTRY_URL: ${{ inputs.REGISTRY_URL }} IMAGE_NAME: ${{ inputs.IMAGE_NAME }} IMAGE_TAG: ${{ inputs.IMAGE_TAG }} - run: docker pull "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" + BUILDAH_ISOLATION: chroot + run: buildah pull "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" shell: bash - name: Tag image env: @@ -60,12 +67,13 @@ runs: IMAGE_NAME: ${{ inputs.IMAGE_NAME }} IMAGE_TAG: ${{ inputs.IMAGE_TAG }} NEW_IMAGE_TAGS: ${{ inputs.NEW_IMAGE_TAGS }} + BUILDAH_ISOLATION: chroot run: | set +e IFS=$'\n' read -r -d '' -a tags <<< "$NEW_IMAGE_TAGS" for tag in "${tags[@]}"; do echo "Tagging image with tag $tag" - docker tag "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" "$REGISTRY_URL/$IMAGE_NAME:$tag" + buildah tag "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" "$REGISTRY_URL/$IMAGE_NAME:$tag" done shell: bash - name: Push image @@ -73,11 +81,12 @@ runs: REGISTRY_URL: ${{ inputs.REGISTRY_URL }} IMAGE_NAME: ${{ inputs.IMAGE_NAME }} NEW_IMAGE_TAGS: ${{ inputs.NEW_IMAGE_TAGS }} + BUILDAH_ISOLATION: chroot run: | set +e IFS=$'\n' read -r -d '' -a tags <<< "$NEW_IMAGE_TAGS" for tag in "${tags[@]}"; do - docker push "$REGISTRY_URL/$IMAGE_NAME:$tag"; + buildah push "$REGISTRY_URL/$IMAGE_NAME:$tag" done shell: bash - name : Send notification on Mattermost