From 542dbb5111b99ff1f5de51d2550dc0198919e354 Mon Sep 17 00:00:00 2001 From: Ganesh Tiwari Date: Fri, 26 Jun 2026 19:04:12 +0530 Subject: [PATCH 1/9] feat: add support for specifying plugins and plugin-dir Signed-off-by: Ganesh Tiwari --- action/action.yml | 88 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/action/action.yml b/action/action.yml index 5642ccfd..503b32ef 100644 --- a/action/action.yml +++ b/action/action.yml @@ -12,17 +12,32 @@ inputs: description: "arch can be amd64, arm64 or arm" required: false deprecationMessage: "No longer required, action will now detect runner arch." + plugins: + description: > + Plugins to install alongside Flux. One per line: `@`. Example: `mirror@0.0.1` + required: false + plugin-dir: + description: > + Directory where the plugins should be installed, setups the `FLUXCD_PLUGINS` env variable. + defaults to be installed alongside flux installation directory in $RUNNER_TOOL_CACHE in a child dir named `/plugins` + required: false bindir: description: "Alternative location for the Flux binary, defaults to path relative to $RUNNER_TOOL_CACHE." required: false token: description: "Token used to authenticate against the GitHub.com API." required: false +outputs: + plugin-dir: + description: > + Directory where the plugins were installed by the action. + value: ${{ steps.set-outputs.outputs.plugin-dir }} runs: using: composite steps: - name: "Download the binary to the runner's cache dir" shell: bash + id: setup-flux-bin env: VERSION: "${{ inputs.version }}" FLUX_TOOL_DIR: "${{ inputs.bindir }}" @@ -42,11 +57,13 @@ runs: if [[ $VERSION = v* ]]; then VERSION="${VERSION:1}" fi + echo installed-flux-version="$VERSION" >> $GITHUB_OUTPUT OS=$(echo "${RUNNER_OS}" | tr '[:upper:]' '[:lower:]') if [[ "$OS" == "macos" ]]; then OS="darwin" fi + echo os="$OS" >> $GITHUB_OUTPUT ARCH=$(echo "${RUNNER_ARCH}" | tr '[:upper:]' '[:lower:]') if [[ "$ARCH" == "x64" ]]; then @@ -54,6 +71,7 @@ runs: elif [[ "$ARCH" == "x86" ]]; then ARCH="386" fi + echo arch="$ARCH" >> $GITHUB_OUTPUT FLUX_EXEC_FILE="flux" if [[ "$OS" == "windows" ]]; then @@ -79,7 +97,7 @@ runs: MAX_RETRIES=5 RETRY_DELAY=5 - + for i in $(seq 1 $MAX_RETRIES); do echo "Downloading flux binary (attempt $i/$MAX_RETRIES)" if curl -fsSL -o "$DL_DIR/$FLUX_TARGET_FILE" "$FLUX_DOWNLOAD_URL/$FLUX_TARGET_FILE"; then @@ -93,7 +111,7 @@ runs: exit 1 fi done - + for i in $(seq 1 $MAX_RETRIES); do echo "Downloading checksums file (attempt $i/$MAX_RETRIES)" if curl -fsSL -o "$DL_DIR/$FLUX_CHECKSUMS_FILE" "$FLUX_DOWNLOAD_URL/$FLUX_CHECKSUMS_FILE"; then @@ -107,7 +125,7 @@ runs: exit 1 fi done - + echo "Verifying checksum" sum="" if command -v openssl > /dev/null; then @@ -129,7 +147,7 @@ runs: echo "Installing flux to ${FLUX_TOOL_DIR}" mkdir -p "$FLUX_TOOL_DIR" - + if [[ "$OS" == "windows" ]]; then unzip "$DL_DIR/$FLUX_TARGET_FILE" "$FLUX_EXEC_FILE" -d "$FLUX_TOOL_DIR" else @@ -146,3 +164,65 @@ runs: shell: bash run: | flux -v + + - name: "Plugin support gate" + id: plugin-support-gate + shell: bash + if: inputs.plugins != '' + env: + V1: ${{ steps.setup-flux-bin.outputs.installed-flux-version }} + run: | + if [ "$(printf '%s\n%s' "$V1" "2.9.0" | sort -V | tail -n1)" = "$V1" ]; then + echo plugin-support="yes" >> $GITHUB_OUTPUT + exit 0 + else + echo plugin-support="no" >> $GITHUB_OUTPUT + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Installed flux version: $V1, does not support plugins. needed >= 2.9.0" >> $GITHUB_STEP_SUMMARY + echo "> Requested plugins cannot be installed." >> $GITHUB_STEP_SUMMARY + exit 1 + fi + + - name: "Setup Plugins Dir" + shell: bash + if: steps.plugin-support-gate.outputs.plugin-support == 'yes' + env: + PLUGINS: ${{ inputs.plugins }} + FLUXCD_PLUGINS: ${{ inputs.plugin-dir }} + VERSION: ${{ steps.setup-flux-bin.outputs.installed-flux-version }} + OS: ${{ steps.setup-flux-bin.outputs.os }} + ARCH: ${{ steps.setup-flux-bin.outputs.arch }} + run: | + # if a plugin dir was not provided, create one + if [[ -z $FLUXCD_PLUGINS ]] then + FLUXCD_PLUGINS="${RUNNER_TOOL_CACHE}/flux2/${VERSION}/${OS}/${ARCH}/plugins/" + fi + + # set it up as env variable for the subsequent steps as well + echo FLUXCD_PLUGINS="$FLUXCD_PLUGINS" >> $GITHUB_ENV + + # create the dir if it does not exists + mkdir -p $FLUXCD_PLUGINS + + - name: "Install Plugins" + shell: bash + id: install-plugins + if: steps.plugin-support-gate.outputs.plugin-support == 'yes' + env: + PLUGINS: ${{ inputs.plugins }} + run: | + # Read line by line + echo "$PLUGINS" | while read -r PLUGIN; do + # if $PLUGIN contains some string value and is not empty + if [[ -n $PLUGIN ]] || [[ $PLUGIN ]]; then + echo Installing: "$PLUGIN" + flux plugin install "$PLUGIN" + fi + done + + - name: "Set Output" + id: set-outputs + if: steps.plugin-support-gate.outputs.plugin-support == 'yes' + shell: bash + run: | + echo "plugin-dir=$FLUXCD_PLUGINS" >> $GITHUB_OUTPUT From 2c1eec5c0fb14eadbc77257bf5958ecf2b959378 Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 09:08:39 +0100 Subject: [PATCH 2/9] Make version gate validation error clearer Signed-off-by: Matheus Pimenta --- action/action.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/action/action.yml b/action/action.yml index 503b32ef..070d039c 100644 --- a/action/action.yml +++ b/action/action.yml @@ -177,9 +177,10 @@ runs: exit 0 else echo plugin-support="no" >> $GITHUB_OUTPUT - echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY - echo "> Installed flux version: $V1, does not support plugins. needed >= 2.9.0" >> $GITHUB_STEP_SUMMARY - echo "> Requested plugins cannot be installed." >> $GITHUB_STEP_SUMMARY + msg="Installed Flux version $V1 does not support plugins; need >= 2.9.0. Requested plugins cannot be installed." + echo "::error title=Unsupported Flux version::$msg" + echo "> [!CAUTION]" >> $GITHUB_STEP_SUMMARY + echo "> $msg" >> $GITHUB_STEP_SUMMARY exit 1 fi From 456d935ae11c230b6299a798d6faf3179f468a8d Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 09:18:17 +0100 Subject: [PATCH 3/9] Make plugin support gate rely on the CLI behavior instead of semver Signed-off-by: Matheus Pimenta --- action/action.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/action/action.yml b/action/action.yml index 070d039c..5ae0597d 100644 --- a/action/action.yml +++ b/action/action.yml @@ -169,15 +169,14 @@ runs: id: plugin-support-gate shell: bash if: inputs.plugins != '' - env: - V1: ${{ steps.setup-flux-bin.outputs.installed-flux-version }} run: | - if [ "$(printf '%s\n%s' "$V1" "2.9.0" | sort -V | tail -n1)" = "$V1" ]; then + flux_version="$(flux -v 2>/dev/null | awk '{print $3}')" + if flux plugin --help >/dev/null 2>&1; then echo plugin-support="yes" >> $GITHUB_OUTPUT exit 0 else echo plugin-support="no" >> $GITHUB_OUTPUT - msg="Installed Flux version $V1 does not support plugins; need >= 2.9.0. Requested plugins cannot be installed." + msg="Installed Flux version ${flux_version:-unknown} does not support plugins; need >= 2.9.0. Requested plugins cannot be installed." echo "::error title=Unsupported Flux version::$msg" echo "> [!CAUTION]" >> $GITHUB_STEP_SUMMARY echo "> $msg" >> $GITHUB_STEP_SUMMARY From c888f28b2c5bd1d76021db02b26ba6b07b08bd78 Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 09:40:46 +0100 Subject: [PATCH 4/9] Improve plugin-dir description Signed-off-by: Matheus Pimenta --- action/action.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/action/action.yml b/action/action.yml index 5ae0597d..3daa1ef9 100644 --- a/action/action.yml +++ b/action/action.yml @@ -18,8 +18,9 @@ inputs: required: false plugin-dir: description: > - Directory where the plugins should be installed, setups the `FLUXCD_PLUGINS` env variable. - defaults to be installed alongside flux installation directory in $RUNNER_TOOL_CACHE in a child dir named `/plugins` + Directory where requested plugins are installed. When plugins are installed, + the action exports `FLUXCD_PLUGINS` for subsequent steps. Defaults to a + `plugins` directory alongside the Flux binary in $RUNNER_TOOL_CACHE. required: false bindir: description: "Alternative location for the Flux binary, defaults to path relative to $RUNNER_TOOL_CACHE." @@ -193,15 +194,15 @@ runs: OS: ${{ steps.setup-flux-bin.outputs.os }} ARCH: ${{ steps.setup-flux-bin.outputs.arch }} run: | - # if a plugin dir was not provided, create one + # Use a default plugin directory when plugin-dir was not provided. if [[ -z $FLUXCD_PLUGINS ]] then FLUXCD_PLUGINS="${RUNNER_TOOL_CACHE}/flux2/${VERSION}/${OS}/${ARCH}/plugins/" fi - # set it up as env variable for the subsequent steps as well + # Export it so subsequent steps can discover the installed plugins. echo FLUXCD_PLUGINS="$FLUXCD_PLUGINS" >> $GITHUB_ENV - # create the dir if it does not exists + # Create the directory if it does not exist. mkdir -p $FLUXCD_PLUGINS - name: "Install Plugins" From 8daa9b9ddfc5d36c70eddd1052241ed34e39bd6d Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 10:02:54 +0100 Subject: [PATCH 5/9] Add quotes to shell vars Signed-off-by: Matheus Pimenta --- action/action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/action/action.yml b/action/action.yml index 3daa1ef9..c9ce9acd 100644 --- a/action/action.yml +++ b/action/action.yml @@ -195,15 +195,15 @@ runs: ARCH: ${{ steps.setup-flux-bin.outputs.arch }} run: | # Use a default plugin directory when plugin-dir was not provided. - if [[ -z $FLUXCD_PLUGINS ]] then + if [[ -z "$FLUXCD_PLUGINS" ]]; then FLUXCD_PLUGINS="${RUNNER_TOOL_CACHE}/flux2/${VERSION}/${OS}/${ARCH}/plugins/" fi # Export it so subsequent steps can discover the installed plugins. - echo FLUXCD_PLUGINS="$FLUXCD_PLUGINS" >> $GITHUB_ENV + echo "FLUXCD_PLUGINS=$FLUXCD_PLUGINS" >> "$GITHUB_ENV" # Create the directory if it does not exist. - mkdir -p $FLUXCD_PLUGINS + mkdir -p "$FLUXCD_PLUGINS" - name: "Install Plugins" shell: bash From 72c2a83e4f9d7785d227b4f385aef82d82bb42f8 Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 10:04:56 +0100 Subject: [PATCH 6/9] Simplify and sanitize plugin line parsing Signed-off-by: Matheus Pimenta --- action/action.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/action/action.yml b/action/action.yml index c9ce9acd..f62b7712 100644 --- a/action/action.yml +++ b/action/action.yml @@ -212,10 +212,9 @@ runs: env: PLUGINS: ${{ inputs.plugins }} run: | - # Read line by line echo "$PLUGINS" | while read -r PLUGIN; do - # if $PLUGIN contains some string value and is not empty - if [[ -n $PLUGIN ]] || [[ $PLUGIN ]]; then + trimmed="${PLUGIN//[[:space:]]/}" + if [[ -n "$trimmed" ]]; then echo Installing: "$PLUGIN" flux plugin install "$PLUGIN" fi From bbf064e4fca5f57b362ec125a5d402a8636e951c Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 10:09:24 +0100 Subject: [PATCH 7/9] Remove unneeded step env var Signed-off-by: Matheus Pimenta --- action/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/action/action.yml b/action/action.yml index f62b7712..3abbe665 100644 --- a/action/action.yml +++ b/action/action.yml @@ -188,7 +188,6 @@ runs: shell: bash if: steps.plugin-support-gate.outputs.plugin-support == 'yes' env: - PLUGINS: ${{ inputs.plugins }} FLUXCD_PLUGINS: ${{ inputs.plugin-dir }} VERSION: ${{ steps.setup-flux-bin.outputs.installed-flux-version }} OS: ${{ steps.setup-flux-bin.outputs.os }} From 4b7e9eef43a5cf6cd5a6145283b2ebcc546a2b78 Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 10:44:24 +0100 Subject: [PATCH 8/9] Add docs and tests for plugins setup Signed-off-by: Matheus Pimenta --- .github/workflows/action.yaml | 38 +++++++++++++++++++++++++++++++++++ action/README.md | 19 ++++++++++++++++++ action/action.yml | 21 ++++++++++--------- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/.github/workflows/action.yaml b/.github/workflows/action.yaml index e19c3130..a3f3950e 100644 --- a/.github/workflows/action.yaml +++ b/.github/workflows/action.yaml @@ -27,3 +27,41 @@ jobs: uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup flux uses: ./action + + plugins: + runs-on: ubuntu-latest + name: action plugins on ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Setup Go + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version-file: go.mod + cache-dependency-path: go.sum + - name: Build flux + shell: bash + run: | + set -euo pipefail + mkdir -p cmd/flux/manifests "$RUNNER_TEMP/flux-bin" + printf "apiVersion: v1\nkind: List\nitems: []\n" > cmd/flux/manifests/dummy.yaml + CGO_ENABLED=0 go build -ldflags="-s -w -X main.VERSION=0.0.0-pr" -o "$RUNNER_TEMP/flux-bin/flux" ./cmd/flux + - name: Setup flux with plugin + id: setup + uses: ./action + with: + version: 0.0.0-pr + bindir: ${{ runner.temp }}/flux-bin + plugins: | + mirror@sha256:91a1e04c2015ee66b1633e362cdb6d4550891b91bf3391a83414b9e9912e53f1 + - name: Assert plugin installation + shell: bash + env: + ACTION_PLUGIN_DIR: ${{ steps.setup.outputs['plugin-dir'] }} + run: | + set -euo pipefail + test -n "${FLUXCD_PLUGINS:-}" + test "$ACTION_PLUGIN_DIR" = "$FLUXCD_PLUGINS" + test -x "$FLUXCD_PLUGINS/flux-mirror" + flux plugin list + flux mirror --help diff --git a/action/README.md b/action/README.md index d511dc9c..5921acfe 100644 --- a/action/README.md +++ b/action/README.md @@ -12,6 +12,25 @@ steps: run: flux version --client ``` +To install Flux plugins alongside the CLI: + +```yaml +steps: + - name: Setup Flux CLI + uses: fluxcd/flux2/action@main + with: + plugins: | + mirror@0.0.1 + - name: Run Flux plugin + run: flux mirror --help +``` + +Installing plugins requires a Flux version with plugin support (v2.9.0 or later). +The `plugins` input accepts one plugin per line in `@` +format. The `plugin-dir` input is only used when `plugins` is set; when +plugins are installed, the action exports `FLUXCD_PLUGINS` for subsequent +steps. + The Flux GitHub Action can be used to automate various tasks in CI, such as: - [Automate Flux upgrades on clusters via Pull Requests](https://fluxcd.io/flux/flux-gh-action/#automate-flux-updates) diff --git a/action/action.yml b/action/action.yml index 3abbe665..c81cfddb 100644 --- a/action/action.yml +++ b/action/action.yml @@ -18,9 +18,10 @@ inputs: required: false plugin-dir: description: > - Directory where requested plugins are installed. When plugins are installed, - the action exports `FLUXCD_PLUGINS` for subsequent steps. Defaults to a - `plugins` directory alongside the Flux binary in $RUNNER_TOOL_CACHE. + Directory where requested plugins are installed. This input is only used when + `plugins` is set. When plugins are installed, the action exports + `FLUXCD_PLUGINS` for subsequent steps. Defaults to a `plugins` directory + alongside the Flux binary in $RUNNER_TOOL_CACHE. required: false bindir: description: "Alternative location for the Flux binary, defaults to path relative to $RUNNER_TOOL_CACHE." @@ -58,13 +59,13 @@ runs: if [[ $VERSION = v* ]]; then VERSION="${VERSION:1}" fi - echo installed-flux-version="$VERSION" >> $GITHUB_OUTPUT + echo "installed-flux-version=$VERSION" >> "$GITHUB_OUTPUT" OS=$(echo "${RUNNER_OS}" | tr '[:upper:]' '[:lower:]') if [[ "$OS" == "macos" ]]; then OS="darwin" fi - echo os="$OS" >> $GITHUB_OUTPUT + echo "os=$OS" >> "$GITHUB_OUTPUT" ARCH=$(echo "${RUNNER_ARCH}" | tr '[:upper:]' '[:lower:]') if [[ "$ARCH" == "x64" ]]; then @@ -72,7 +73,7 @@ runs: elif [[ "$ARCH" == "x86" ]]; then ARCH="386" fi - echo arch="$ARCH" >> $GITHUB_OUTPUT + echo "arch=$ARCH" >> "$GITHUB_OUTPUT" FLUX_EXEC_FILE="flux" if [[ "$OS" == "windows" ]]; then @@ -82,7 +83,7 @@ runs: if [[ -z "$FLUX_TOOL_DIR" ]]; then FLUX_TOOL_DIR="${RUNNER_TOOL_CACHE}/flux2/${VERSION}/${OS}/${ARCH}" fi - if [[ ! -x "$FLUX_TOOL_DIR/FLUX_EXEC_FILE" ]]; then + if [[ ! -x "$FLUX_TOOL_DIR/$FLUX_EXEC_FILE" ]]; then DL_DIR="$(mktemp -dt flux2-XXXXXX)" trap 'rm -rf $DL_DIR' EXIT @@ -173,10 +174,10 @@ runs: run: | flux_version="$(flux -v 2>/dev/null | awk '{print $3}')" if flux plugin --help >/dev/null 2>&1; then - echo plugin-support="yes" >> $GITHUB_OUTPUT + echo "plugin-support=yes" >> "$GITHUB_OUTPUT" exit 0 else - echo plugin-support="no" >> $GITHUB_OUTPUT + echo "plugin-support=no" >> "$GITHUB_OUTPUT" msg="Installed Flux version ${flux_version:-unknown} does not support plugins; need >= 2.9.0. Requested plugins cannot be installed." echo "::error title=Unsupported Flux version::$msg" echo "> [!CAUTION]" >> $GITHUB_STEP_SUMMARY @@ -224,4 +225,4 @@ runs: if: steps.plugin-support-gate.outputs.plugin-support == 'yes' shell: bash run: | - echo "plugin-dir=$FLUXCD_PLUGINS" >> $GITHUB_OUTPUT + echo "plugin-dir=$FLUXCD_PLUGINS" >> "$GITHUB_OUTPUT" From ca5347f4b417008c31cf793a436c229971d4a132 Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Mon, 29 Jun 2026 11:14:14 +0100 Subject: [PATCH 9/9] Improve docs for plugins action installation Signed-off-by: Matheus Pimenta --- action/README.md | 9 +++++---- action/action.yml | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/action/README.md b/action/README.md index 5921acfe..0a09132f 100644 --- a/action/README.md +++ b/action/README.md @@ -26,10 +26,11 @@ steps: ``` Installing plugins requires a Flux version with plugin support (v2.9.0 or later). -The `plugins` input accepts one plugin per line in `@` -format. The `plugin-dir` input is only used when `plugins` is set; when -plugins are installed, the action exports `FLUXCD_PLUGINS` for subsequent -steps. +The `plugins` input accepts one plugin per line in ``, +`@`, or `@` format. Entries without a version or +digest install the latest version from the catalog. The `plugin-dir` input is +only used when `plugins` is set; when plugins are installed, the action exports +`FLUXCD_PLUGINS` for subsequent steps. The Flux GitHub Action can be used to automate various tasks in CI, such as: diff --git a/action/action.yml b/action/action.yml index c81cfddb..330166f7 100644 --- a/action/action.yml +++ b/action/action.yml @@ -14,7 +14,9 @@ inputs: deprecationMessage: "No longer required, action will now detect runner arch." plugins: description: > - Plugins to install alongside Flux. One per line: `@`. Example: `mirror@0.0.1` + Plugins to install alongside Flux. One per line: ``, `@` or + `@`. Entries without a version or digest install the latest + version from the catalog. Example: `mirror@0.0.1` required: false plugin-dir: description: >