name: "Dagger for GitHub" description: "Run dagger commands in Github Actions" inputs: version: description: "Dagger Version. Use semver vX.Y.Z or 'latest'" required: false default: "latest" commit: description: "Dagger Dev Commit" required: false default: "" dagger-flags: description: "Dagger CLI Flags" required: false default: "--progress plain" verb: description: "CLI verb (call, run, download, up, functions, shell, query)" required: false default: "call" workdir: description: "The working directory in which to run the Dagger CLI" required: false default: "." cloud-token: description: "Dagger Cloud Token" required: false default: "" module: description: "Dagger module to call. Local or Git" required: false default: "" args: description: "Arguments to pass to CLI" required: false default: "" engine-stop: description: "Deprecated" deprecationMessage: "engine-stop is now a no-op and will be removed in a future release" required: false call: description: "Function and arguments for dagger call" required: false default: "" shell: description: "Function and arguments for dagger shell" required: false default: "" summary-path: description: "File path to write the job summary" required: false default: "" enable-github-summary: description: "Whether to write summary to GITHUB_STEP_SUMMARY" required: false default: "false" outputs: output: description: "Job output" value: ${{ steps.exec.outputs.stdout }} traceURL: description: "Dagger Cloud trace URL" value: ${{ steps.exec.outputs.traceURL }} runs: using: "composite" steps: - shell: bash run: | set -o pipefail # Fallback to /usr/local for backwards compatability prefix_dir="${RUNNER_TEMP:-/usr/local}" # Ensure the dir is writable otherwise fallback to tmpdir if [[ ! -d "$prefix_dir" ]] || [[ ! -w "$prefix_dir" ]]; then prefix_dir="$(mktemp -d)" fi printf '%s/bin' "$prefix_dir" >> $GITHUB_PATH # If the dagger version is 'latest', set the version back to an empty # string. This allows the install script to detect and install the latest # version itself VERSION=${{ inputs.version }} if [[ "$VERSION" == "latest" ]]; then VERSION= elif [[ -n "$VERSION" && "$VERSION" != v* ]]; then # Add 'v' prefix if version doesn't start with 'v' and is not empty VERSION="v$VERSION" fi latest=$(curl https://dl.dagger.io/dagger/versions/latest) COMMIT=${{ inputs.commit }} if [[ -x "$(command -v dagger)" ]]; then echo "::group::Checking dagger" version="$(dagger --silent version | cut --fields 2 --delimiter ' ')" echo "Found existing dagger version: $version" if [[ "$version" == "$VERSION" ]] || [[ "$version" == "$latest" ]]; then echo "dagger ${version} is already installed, skipping installation" exit 0 fi echo "::endgroup::" fi echo "::group::Installing dagger" curl -fsSL https://dl.dagger.io/dagger/install.sh | \ BIN_DIR=${prefix_dir}/bin DAGGER_VERSION="$VERSION" DAGGER_COMMIT="$COMMIT" sh echo "::endgroup::" - id: assemble if: inputs.call != '' || inputs.shell != '' || inputs.args != '' shell: bash env: INPUT_MODULE: ${{ inputs.module }} run: | verb=${{ inputs.verb }} shell=$(echo '${{ toJSON(inputs.shell) }}' | jq -rj .) dagger_flags=$(echo '${{ toJSON(inputs.dagger-flags) }}' | jq -rj .) args=$(echo '${{ toJSON(inputs.args) }}' | jq -rj .) call=$(echo '${{ toJSON(inputs.call) }}' | jq -rj .) if [[ -n "${{ inputs.call }}" ]]; then verb="call" elif [[ "$shell" != "" ]]; then verb="" script=$(mktemp) printf '%s' "$shell" > $script fi echo "script=$script" >> "$GITHUB_OUTPUT" echo "verb=$verb" >> "$GITHUB_OUTPUT" echo "dagger-flags=$dagger_flags" >> "$GITHUB_OUTPUT" echo "args=$args" >> "$GITHUB_OUTPUT" echo "call=$call" >> "$GITHUB_OUTPUT" - id: exec if: inputs.call != '' || inputs.shell != '' || inputs.args != '' shell: bash env: INPUT_MODULE: ${{ inputs.module }} VERB: ${{ steps.assemble.outputs.verb }} CMD: ${{ steps.assemble.outputs.args || steps.assemble.outputs.call || steps.assemble.outputs.script }} SCRIPT: ${{ steps.assemble.outputs.script }} run: | tmpout=$(mktemp) tmperr=$(mktemp) cd ${{ inputs.workdir }} && { \ DAGGER_CLOUD_TOKEN=${{ inputs.cloud-token }} \ dagger \ ${{ steps.assemble.outputs.dagger-flags }} \ ${{ steps.assemble.outputs.verb }} \ ${INPUT_MODULE:+-m $INPUT_MODULE} \ ${{ steps.assemble.outputs.args || steps.assemble.outputs.call || steps.assemble.outputs.script }}; } 1> >(tee "${tmpout}") 2> >(tee "${tmperr}" >&2) { # we need a delim that doesn't appear in the output - a hash of the # file itself *probably* won't (if it does, we have larger # cryptographic problems) delim="$(sha256sum $tmpout | cut -d " " -f1)" echo "stdout<<${delim}" cat "${tmpout}" echo echo "${delim}" } >> "$GITHUB_OUTPUT" # Extract trace URL from stderr and set as traceURL output trace_url=$((grep -Eo 'https://dagger.cloud(/[^ ]+/traces/[a-zA-Z0-9]+|/traces/setup)' "${tmperr}" || true) | head -n1) if [[ -n "$trace_url" ]]; then echo "traceURL=$trace_url" >> "$GITHUB_OUTPUT" fi # Generate job summary content summary_content(){ echo -e "## Command\n" echo '```bash' cmd="dagger $VERB $CMD" if [[ -n "$INPUT_MODULE" ]]; then echo -e -E "DAGGER_MODULE=\"$INPUT_MODULE\" $cmd" else echo -e -E "$cmd" fi echo '```' if [[ -n "$SCRIPT" ]]; then echo -e "### Script\n" echo '```bash' cat "$SCRIPT" echo -e "\n" echo '```' fi echo -e "## Dagger trace\n" if [[ -n "$trace_url" ]]; then echo "[$trace_url]($trace_url)" else echo "No trace available. To setup: [https://dagger.cloud/traces/setup](https://dagger.cloud/traces/setup)" fi echo -e "## Dagger version\n" echo '```bash' dagger version || true echo '```' echo -e "---\n" } # Write to custom summary path if specified if [[ -n "${{ inputs.summary-path }}" ]]; then summary_content > "${{ inputs.summary-path }}" fi # Write to GitHub step summary if enabled (default: true) if [[ "${{ inputs.enable-github-summary }}" == "true" ]]; then summary_content > "${GITHUB_STEP_SUMMARY}" fi