{"id":11968478,"name":"chainguard-dev/digestabot","ecosystem":"actions","description":"Update the image digest when have a mutating tag","homepage":"","licenses":"apache-2.0","normalized_licenses":["Apache-2.0"],"repository_url":"https://github.com/chainguard-dev/digestabot","keywords_array":[],"namespace":"chainguard-dev","versions_count":13,"first_release_published_at":"2023-11-07T16:24:54.000Z","latest_release_published_at":"2026-06-01T17:55:54.000Z","latest_release_number":"v1.3.2","latest_published_release_number":null,"last_synced_at":"2026-10-06T02:07:23.873Z","created_at":"2025-08-01T10:31:41.057Z","updated_at":"2026-10-06T02:07:29.838Z","registry_url":"https://github.com/chainguard-dev/digestabot","install_command":null,"documentation_url":null,"metadata":{"name":"Update the image digest","description":"Update the image digest when have a mutating tag","inputs":{"working-dir":{"description":"Working directory to run the digestabot, to run in a specific path, if not set will run from the root","required":false,"default":"."},"include-files":{"description":"Files (names or globs, comma-separated) that will be scanned for digest updates.","required":false,"default":"*.yaml,*.yml,Dockerfile*,Makefile*,*.sh,*.tf,*.tfvars"},"token":{"description":"GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT)","required":true,"default":"${{ github.token }}"},"signoff":{"description":"Add `Signed-off-by` line by the committer at the end of the commit log message.","default":false},"author":{"description":"The author name and email address in the format `Display Name \u003cemail@address.com\u003e`. Defaults to the user who triggered the workflow run.\n","default":"${{ github.actor }} \u003c${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com\u003e"},"committer":{"description":"The committer name and email address in the format `Display Name \u003cemail@address.com\u003e`. Defaults to the GitHub Actions bot user.\n","default":"github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"},"labels-for-pr":{"description":"A comma or newline separated list of labels to be used in the pull request.","default":"automated pr, kind/cleanup, release-note-none"},"branch-for-pr":{"description":"The pull request branch name.","default":"update-digests"},"title-for-pr":{"description":"The title of the pull request.","default":"Update images digests"},"description-for-pr":{"description":"The description of the pull request.","default":"Update images digests\n\n```release-note\nNONE\n```\n"},"commit-message":{"description":"The message to use when committing changes.","default":"Update images digests"},"create-pr":{"description":"Create a PR or just keep the changes locally.","default":true},"use-gitsign":{"description":"Use gitsign to sign commits.","default":"true"},"registry-map":{"description":"Comma-separated registry prefix mappings (proxy=upstream) for digest lookups. e.g. us-docker.pkg.dev/my-proj/cgr/=cgr.dev/","required":false,"default":""},"min-age":{"description":"Only update to digests pushed at least this many days ago, so a cooldown policy on the registry does not block pulling them. Uses the tag history of the Chainguard registry, so it only applies to cgr.dev images (after `registry-map`); other images are skipped. Disabled when empty or 0.","required":false,"default":""},"stale-after":{"description":"Warn about image tags that were not rebuilt in this many days, as they may have reached their end of life and no longer receive patches. Uses the build time of the image (`org.opencontainers.image.created`); images without one are skipped. Disabled when empty or 0.","required":false,"default":""},"verify-signatures":{"description":"Verify the cosign signature of the new digests before updating them. A YAML list of rules mapping image prefixes to the expected certificate identity and issuer, or the path of a file with it. Updates whose signature cannot be verified are skipped; images not matched by any rule are not verified. Disabled when empty.","required":false,"default":""},"sbom-diff":{"description":"List the package changes of each updated image in the job summary and upload them as a workflow artifact, based on its SPDX SBOM attestation. Images without an SBOM are skipped.","default":"false"},"sbom-platform":{"description":"Platform of the image whose SBOM is used for the package changes.","default":"linux/amd64"},"sbom-diff-artifact-name":{"description":"Name of the workflow artifact with the package changes (`sbom-diff.json` and `sbom-diff.md`). Must be unique within the workflow run.","default":"digestabot-sbom-diff"}},"outputs":{"pull_request_number":{"description":"Pull Request Number","value":"${{ steps.pull_request.outputs.pull_request_number }}"},"json":{"description":"The changes made by this action, in json format.\n\nThe output follows this structure:\n\n```\n{\n  \"updates\": [\n    {\n      \"file\": \".ko.yaml\",\n      \"image\": \"cgr.dev/chainguard/kubectl:latest-dev\",\n      \"digest\": \"sha256:d5f340d044438351413d6cb110f6f8a2abc45a7149aa53e6ade719f069fc3b0a\",\n      \"updated_digest\": \"sha256:cd90036b16413eed13818500ae837e6e7710a59c74144c32e1e90b0e59d22efc\"\n    }\n  ]\n}\n```\n","value":"${{ steps.update_files.outputs.json }}"},"changed_files":{"description":"A newline-separated list of files that were modified during the digest update process.\nOnly includes files that actually had their digests updated.\n","value":"${{ steps.update_files.outputs.changed_files }}"},"sbom_diff":{"description":"Markdown summary of the package changes of each updated image, based on its SPDX SBOM attestation.\nEmpty when `sbom-diff` is disabled or no digest was updated.\n","value":"${{ steps.sbom_diff.outputs.sbom_diff }}"},"sbom_diff_artifact_url":{"description":"URL of the workflow artifact with the package changes. Empty when `sbom-diff` is disabled or no digest was updated.","value":"${{ steps.upload_sbom_diff.outputs.artifact-url }}"},"stale_tags":{"description":"The image tags that were not rebuilt in the last `stale-after` days, in json format.\nEmpty when `stale-after` is disabled.\n\nThe output follows this structure:\n\n```\n[\n  {\n    \"image\": \"cgr.dev/chainguard/python:3.9\",\n    \"lookup_image\": \"cgr.dev/chainguard/python:3.9\",\n    \"files\": [\"Dockerfile\"],\n    \"created\": \"2026-06-01T00:00:00Z\",\n    \"age_days\": 120\n  }\n]\n```\n","value":"${{ steps.stale_tags.outputs.stale_tags }}"},"verification_failures":{"description":"The updates that were skipped because the signature of the new digest could not be verified, in json format.\nEmpty when `verify-signatures` is disabled.\n\nThe output follows this structure:\n\n```\n[\n  {\n    \"file\": \"Dockerfile\",\n    \"image\": \"cgr.dev/chainguard/static:latest\",\n    \"digest\": \"sha256:a117fb6e8c62246fe60e40eaa0c2cb51575db8cec42c114bc5a9d4cb89d94fee\",\n    \"updated_digest\": \"sha256:41e17ed83c594a64a9396b6ab96dd26d5ddc290dacf4c177464712ff21ad534f\",\n    \"error\": \"no matching signatures\"\n  }\n]\n```\n","value":"${{ steps.update_files.outputs.verification_failures }}"}},"runs":{"using":"composite","steps":[{"name":"Install crane","id":"install_crane","shell":"bash","run":"set -euo pipefail\n\n# Pin crane version and checksums\nCRANE_VERSION=\"v0.21.3\"\n\n# Detect architecture\narch=$(uname -m)\nif [[ \"$arch\" =~ (aarch64|arm64) ]]; then\n  arch=\"arm64\"\n  EXPECTED_CHECKSUM=\"dabcf2aee76ca72da63b5da5137c910a6852ccff13e35628e8f0a9dd8b73f4f3\"\nelse\n  arch=\"x86_64\"\n  EXPECTED_CHECKSUM=\"46dbf12d943efa5673ab654186c5d7c1503580544de0df9325537083436fe5d0\"\nfi\n\necho \"Installing crane ${CRANE_VERSION} for Linux ${arch}\"\n\n# Download crane from official GitHub releases\ncrane_tar=\"go-containerregistry_Linux_${arch}.tar.gz\"\ncrane_url=\"https://github.com/google/go-containerregistry/releases/download/${CRANE_VERSION}/${crane_tar}\"\n\ncurl -fsSL --retry 5 --retry-delay 1 --retry-all-errors -o \"${crane_tar}\" \"${crane_url}\"\n\n# Verify SHA256 checksum\necho \"${EXPECTED_CHECKSUM}  ${crane_tar}\" | sha256sum --check --strict -\n\n# Extract directly to the destination and expose the explicit binary path\n# to later steps so they do not depend on runner PATH propagation.\ncrane_path=\"${HOME}/.local/bin/crane\"\nmkdir -p \"$(dirname \"${crane_path}\")\"\ntar -xzf \"${crane_tar}\" -C \"$(dirname \"${crane_path}\")\" crane\necho \"crane_path=${crane_path}\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n\n# Verify installation\n\"${crane_path}\" version\n\n# Clean up\nrm -f \"${crane_tar}\"\n"},{"name":"Authenticate crane","shell":"bash","env":{"CRANE_PATH":"${{ steps.install_crane.outputs.crane_path }}","INPUTS_TOKEN":"${{ inputs.token }}","GITHUB_ACTOR":"${{ github.actor }}"},"run":"echo \"$INPUTS_TOKEN\" | \"${CRANE_PATH}\" auth login ghcr.io --username \"$GITHUB_ACTOR\" --password-stdin\n"},{"name":"Read the signature policy","id":"signature_policy","if":"${{ inputs.verify-signatures != '' }}","shell":"bash","env":{"ACTION_PATH":"${{ github.action_path }}","VERIFY_SIGNATURES":"${{ inputs.verify-signatures }}"},"run":"policy=\"${RUNNER_TEMP}/digestabot-signature-policy.json\"\n\"${ACTION_PATH}/scripts/signature-policy.sh\" \"${VERIFY_SIGNATURES}\" \u003e \"${policy}\"\necho \"policy=${policy}\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n"},{"name":"Install cosign","if":"${{ steps.signature_policy.outputs.policy != '' }}","uses":"sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6"},{"shell":"bash","id":"update_files","env":{"CRANE_PATH":"${{ steps.install_crane.outputs.crane_path }}","INPUTS_INCLUDE_FILES":"${{ inputs.include-files }}","INPUTS_WORKING_DIR":"${{ inputs.working-dir }}","INPUTS_REGISTRY_MAP":"${{ inputs.registry-map }}","INPUTS_MIN_AGE":"${{ inputs.min-age }}","SIGNATURE_POLICY":"${{ steps.signature_policy.outputs.policy }}","ACTION_PATH":"${{ github.action_path }}"},"run":"# disable the errexit github enable that by default\nset +o errexit\n\nMIN_AGE=\"${INPUTS_MIN_AGE:-0}\"\nif [[ ! \"${MIN_AGE}\" =~ ^[0-9]+$ ]]; then\n  echo \"::error::min-age must be a whole number of days, got '${INPUTS_MIN_AGE}'\"\n  exit 1\nfi\nMIN_AGE=$((10#${MIN_AGE}))\n\nIFS=',' read -ra PATTERNS \u003c\u003c\u003c \"${INPUTS_INCLUDE_FILES}\"\n\nREGISTRY_MAPPINGS=()\nif [ -n \"${INPUTS_REGISTRY_MAP}\" ] ; then\n  IFS=',' read -ra REGISTRY_MAPPINGS \u003c\u003c\u003c \"${INPUTS_REGISTRY_MAP}\"\nfi\n\n# image, lookup image and old/new digest of every update, consumed by the SBOM diff step\nsbom_targets=\"${RUNNER_TEMP}/digestabot-sbom-targets.tsv\"\n: \u003e \"${sbom_targets}\"\n\n# file, image and lookup image of every image, consumed by the stale tags step\nimage_targets=\"${RUNNER_TEMP}/digestabot-images.tsv\"\n: \u003e \"${image_targets}\"\n\n# digests already resolved, so an image referenced in several places is looked up once\ndeclare -A resolved_digests\n\n# signature verification result per image digest, and the updates skipped\ndeclare -A verified\nverification_failures='[]'\n\njson='{}'\nchanged_files=()\nwhile IFS= read -r -d '' file; do\n  if [[ \"$file\" == *testdata* ]]; then\n    echo \"Skipping testdata ${file}\"\n    continue\n  fi\n\n  # Extract all image references and their digests\n  mapfile -t image_lines \u003c \u003c(grep -i -E '[a-z0-9]+([._-][a-z0-9]+)*(/[a-z0-9]+([._-][a-z0-9]+)*)*@sha256:[a-z0-9]+' \"$file\" || true)\n\n  for line in \"${image_lines[@]}\"; do\n    image=$(echo \"$line\" | cut -d @ -f1 | rev | cut -d = -f1 | cut -d ' ' -f1 | cut -d '\"' -f1 | rev | sed -e \"s/^docker:\\/\\///\" | tr -d '' | tr -d '\\t')\n    # Extract exactly the sha256 digest (64 hex chars). Using grep -oE\n    # instead of cut to avoid capturing adjacent syntax characters like\n    # } in shell scripts (e.g. ${VAR:=image@sha256:...}\") or ' in YAML\n    # (e.g. 'image@sha256:...'), which the old cut pipeline would include\n    # in the digest and then sed would delete during replacement.\n    digest=$(echo \"$line\"| grep -oE 'sha256:[a-f0-9]{64}' | head -1)\n\n    if [[ \"$image\" != *\":\"* ]]; then\n      echo \"Image $image in file $file does not have a tag, ignoring...\"\n      continue\n    fi\n    if [[ \"$image\" == *\\.local:* ]]; then\n      echo \"Skipping local registry image $image\"\n      continue\n    fi\n\n    echo \"Processing $image in file $file\"\n\n    lookup_image=\"$image\"\n    for mapping in \"${REGISTRY_MAPPINGS[@]}\"; do\n      proxy=\"${mapping%%=*}\"\n      upstream=\"${mapping#*=}\"\n      if [[ \"$lookup_image\" == \"${proxy}\"* ]]; then\n        lookup_image=\"${upstream}${lookup_image#\"${proxy}\"}\"\n        echo \"  Registry mapping: querying $lookup_image instead of $image\"\n        break\n      fi\n    done\n    printf '%s\\t%s\\t%s\\n' \"${file}\" \"${image}\" \"${lookup_image}\" \u003e\u003e \"${image_targets}\"\n\n    # with min-age the result also depends on the current digest,\n    # which is never downgraded\n    cache_key=\"$lookup_image\"\n    [ \"${MIN_AGE}\" -gt 0 ] \u0026\u0026 cache_key=\"$lookup_image@$digest\"\n\n    updated_digest=\n    if [ -n \"${resolved_digests[$cache_key]:-}\" ]; then\n        updated_digest=\"${resolved_digests[$cache_key]}\"\n    elif [ \"${MIN_AGE}\" -gt 0 ] \u0026\u0026 \"${ACTION_PATH}/scripts/cooldown-digest.sh\" \"$lookup_image\" \"$digest\" \"${MIN_AGE}\" \u003e digest.log 2\u003e logerror.txt; then\n        updated_digest=$(cat digest.log)\n        resolved_digests[$cache_key]=\"$updated_digest\"\n    elif [ \"${MIN_AGE}\" -eq 0 ] \u0026\u0026 \"${CRANE_PATH}\" digest \"$lookup_image\" \u003e digest.log 2\u003e logerror.txt; then\n        updated_digest=$(cat digest.log)\n        resolved_digests[$cache_key]=\"$updated_digest\"\n    else\n        ERRMSG=\"Failed to retrieve digest info for $image\"\n        [ \"$lookup_image\" != \"$image\" ] \u0026\u0026 ERRMSG=\"$ERRMSG (upstream: $lookup_image)\"\n        echo \"$ERRMSG\"\n        echo \"$ERRMSG\" \u003e\u003e \"$GITHUB_STEP_SUMMARY\"\n        cat logerror.txt \u003e\u003e \"$GITHUB_STEP_SUMMARY\"\n    fi\n    rm -f logerror.txt\n    rm -f digest.log\n\n    if [ -n \"${SIGNATURE_POLICY}\" ] \u0026\u0026 [ \"$updated_digest\" != \"$digest\" ] \u0026\u0026 [ -n \"$updated_digest\" ]; then\n      verify_key=\"$lookup_image@$updated_digest\"\n      if [ -z \"${verified[$verify_key]:-}\" ]; then\n        \"${ACTION_PATH}/scripts/verify-signature.sh\" \"${SIGNATURE_POLICY}\" \"$lookup_image\" \"$updated_digest\" 2\u003e verify.log\n        case $? in\n          0) verified[$verify_key]=ok ;;\n          3) verified[$verify_key]=ok; echo \"  No signature rule matches $lookup_image, not verifying it\" ;;\n          *) verified[$verify_key]=$(grep -v '^Verifying the signature' verify.log | tail -n 1 | sed -e 's/^error during command execution: //')\n             verified[$verify_key]=${verified[$verify_key]:-signature verification failed} ;;\n        esac\n        cat verify.log\n        rm -f verify.log\n      fi\n      if [ \"${verified[$verify_key]}\" != ok ]; then\n        error=\"${verified[$verify_key]}\"\n        line=$(grep -n -F -m 1 \"$image@$digest\" \"$file\" | cut -d : -f 1)\n        echo \"::warning file=${file},line=${line:-1},title=Signature verification failed::Not updating ${image} to ${updated_digest}: ${error}\"\n        verification_failures=$(jq -c \\\n          --arg file \"${file}\" --arg image \"${image}\" --arg digest \"${digest}\" \\\n          --arg updated_digest \"${updated_digest}\" --arg error \"${error}\" \\\n          '. += [{file: $file, image: $image, digest: $digest, updated_digest: $updated_digest, error: $error}]' \u003c\u003c\u003c\"${verification_failures}\")\n        updated_digest=\n      fi\n    fi\n\n    if [ \"$updated_digest\" != \"$digest\" ] \u0026\u0026 [ -n \"$updated_digest\" ]; then\n      echo \"Digest $digest for image $image is different, new digest is $updated_digest, updating...\"\n      sed -i -e \"s|$image@$digest|$image@$updated_digest|g\" \"$file\"\n      # Add file to changed_files array if not already present\n      # Quoted RHS is intentional: literal match guards against regex\n      # metacharacters in filenames; see docs/backlog.md for refactor note\n      # shellcheck disable=SC2076\n      if [[ ! \" ${changed_files[*]} \" =~ \" ${file} \" ]]; then\n        changed_files+=(\"$file\")\n      fi\n      json=$(jq -c \\\n        --arg file \"${file}\" \\\n        --arg image \"${image}\" \\\n        --arg digest \"${digest}\" \\\n        --arg updated_digest \"${updated_digest}\" \\\n        '.updates += [{file: $file, image: $image, digest: $digest, updated_digest: $updated_digest}]' \u003c\u003c\u003c\"${json}\")\n      printf '%s\\t%s\\t%s\\t%s\\n' \"${image}\" \"${lookup_image}\" \"${digest}\" \"${updated_digest}\" \u003e\u003e \"${sbom_targets}\"\n    fi\n  done\ndone \u003c \u003c(\n    find_args=()\n    for i in \"${!PATTERNS[@]}\"; do\n        if [ \"$i\" -eq 0 ]; then\n            find_args+=(-name \"${PATTERNS[$i]}\")\n        else\n            find_args+=(-o -name \"${PATTERNS[$i]}\")\n        fi\n    done\n    find \"${INPUTS_WORKING_DIR}\" -type f \\( \"${find_args[@]}\" \\) -print0\n)\n\necho \"json=${json}\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n\nif [ -n \"${SIGNATURE_POLICY}\" ]; then\n  echo \"verification_failures=${verification_failures}\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n  jq -r 'if length == 0 then empty else\n      \"## Signature verification failed\\n\\nThese updates were skipped because the signature of the new digest could not be verified.\\n\\n\" +\n      \"| Image | New digest | File | Error |\\n|-------|------------|------|-------|\\n\" +\n      (map(\"| `\\(.image)` | `\\(.updated_digest)` | `\\(.file)` | \\(.error | gsub(\"\\\\|\"; \"\\\\\\\\|\")) |\\n\") | join(\"\"))\n    end' \u003c\u003c\u003c\"${verification_failures}\" \u003e\u003e \"${GITHUB_STEP_SUMMARY}\"\nfi\n\n# Output the list of changed files\nif [ ${#changed_files[@]} -gt 0 ]; then\n  echo \"changed_files\u003c\u003cEOF\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n  printf '%s\\n' \"${changed_files[@]}\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n  echo \"EOF\" \u003e\u003e \"${GITHUB_OUTPUT}\"\nelse\n  echo \"changed_files=\" \u003e\u003e \"${GITHUB_OUTPUT}\"\nfi\n"},{"name":"Diff image SBOMs","id":"sbom_diff","if":"${{ inputs.sbom-diff == 'true' \u0026\u0026 steps.update_files.outputs.changed_files != '' }}","shell":"bash","env":{"ACTION_PATH":"${{ github.action_path }}","CRANE_PATH":"${{ steps.install_crane.outputs.crane_path }}","SBOM_PLATFORM":"${{ inputs.sbom-platform }}"},"run":"out_dir=\"${RUNNER_TEMP}/digestabot-sbom-diff\"\n\"${ACTION_PATH}/scripts/sbom-diff.sh\" \"${out_dir}\" \u003c \"${RUNNER_TEMP}/digestabot-sbom-targets.tsv\"\necho \"dir=${out_dir}\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n\n{ echo \"## Package changes\"; echo; cat \"${out_dir}/sbom-diff.md\"; } \u003e\u003e \"${GITHUB_STEP_SUMMARY}\"\n\ndelimiter=\"EOF_$(openssl rand -hex 16)\"\n{\n  echo \"sbom_diff\u003c\u003c${delimiter}\"\n  cat \"${out_dir}/sbom-diff.md\"\n  echo \"${delimiter}\"\n} \u003e\u003e \"${GITHUB_OUTPUT}\"\n"},{"name":"Upload SBOM diff","id":"upload_sbom_diff","if":"${{ steps.sbom_diff.outputs.dir != '' }}","uses":"actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","with":{"name":"${{ inputs.sbom-diff-artifact-name }}","path":"${{ steps.sbom_diff.outputs.dir }}","if-no-files-found":"error"}},{"name":"Check for stale tags","id":"stale_tags","if":"${{ inputs.stale-after != '' \u0026\u0026 inputs.stale-after != '0' }}","shell":"bash","env":{"ACTION_PATH":"${{ github.action_path }}","CRANE_PATH":"${{ steps.install_crane.outputs.crane_path }}","STALE_AFTER":"${{ inputs.stale-after }}"},"run":"if [[ ! \"${STALE_AFTER}\" =~ ^[0-9]+$ ]]; then\n  echo \"::error::stale-after must be a whole number of days, got '${STALE_AFTER}'\"\n  exit 1\nfi\n\nout_dir=\"${RUNNER_TEMP}/digestabot-stale-tags\"\n\"${ACTION_PATH}/scripts/stale-tags.sh\" \"${STALE_AFTER}\" \"${out_dir}\" \u003c \"${RUNNER_TEMP}/digestabot-images.tsv\"\n\n# annotate the line of every file that uses a stale tag\njq -r '.[] | . as $t | .files[] | [., $t.image, $t.created[:10], $t.age_days] | @tsv' \"${out_dir}/stale-tags.json\" |\n  while IFS=$'\\t' read -r file image created age; do\n    line=$(grep -n -F -m 1 \"${image}@\" \"${file}\" | cut -d : -f 1)\n    echo \"::warning file=${file},line=${line:-1},title=Stale image tag::${image} was last built on ${created} (${age} days ago). The tag may have reached its end of life and no longer receive patches; consider moving to a supported tag.\"\n  done\n\nif [ -s \"${out_dir}/stale-tags.md\" ]; then\n  { echo \"## Stale tags\"; echo; cat \"${out_dir}/stale-tags.md\"; } \u003e\u003e \"${GITHUB_STEP_SUMMARY}\"\nfi\n\necho \"stale_tags=$(jq -c . \"${out_dir}/stale-tags.json\")\" \u003e\u003e \"${GITHUB_OUTPUT}\"\ndelimiter=\"EOF_$(openssl rand -hex 16)\"\n{\n  echo \"stale_tags_md\u003c\u003c${delimiter}\"\n  cat \"${out_dir}/stale-tags.md\"\n  echo \"${delimiter}\"\n} \u003e\u003e \"${GITHUB_OUTPUT}\"\n"},{"name":"Check workspace","id":"create_pr_update","env":{"CREATE_PR":"${{ inputs.create-pr }}"},"shell":"bash","working-directory":"${{ inputs.working-dir }}","run":"git diff --stat\necho \"create_pr_update=false\" \u003e\u003e \"$GITHUB_OUTPUT\"\nif [[ $(git diff --stat) != '' ]] \u0026\u0026 [[ \"${CREATE_PR}\" == 'true' ]]; then\n  echo \"create_pr_update=true\" \u003e\u003e \"$GITHUB_OUTPUT\"\n  echo \"diff\u003c\u003cEOF\" \u003e\u003e \"${GITHUB_OUTPUT}\"\n  git diff \u003e\u003e \"${GITHUB_OUTPUT}\"\n  echo \"EOF\" \u003e\u003e \"${GITHUB_OUTPUT}\"\nfi\n"},{"uses":"chainguard-dev/actions/setup-gitsign@805da2efdffdc42b8afd8880e575a48b471ef544","if":"${{ steps.create_pr_update.outputs.create_pr_update == 'true' \u0026\u0026 inputs.use-gitsign == 'true' }}"},{"name":"Configure git credentials","if":"${{ steps.create_pr_update.outputs.create_pr_update == 'true' }}","shell":"bash","env":{"INPUTS_TOKEN":"${{ inputs.token }}"},"run":"git config --global credential.helper store\necho \"https://x-access-token:${INPUTS_TOKEN}@github.com\" \u003e ~/.git-credentials\n"},{"name":"Create Pull Request","uses":"actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3","if":"${{ steps.create_pr_update.outputs.create_pr_update == 'true' }}","id":"pull_request","env":{"COMMIT_MESSAGE":"${{ inputs.commit-message }}","PR_TITLE":"${{ inputs.title-for-pr }}","PR_BODY":"${{ inputs.description-for-pr }}","PR_DIFF":"${{ steps.create_pr_update.outputs.diff }}","PR_LABELS":"${{ inputs.labels-for-pr }}","PR_BRANCH":"${{ inputs.branch-for-pr }}","AUTHOR":"${{ inputs.author }}","COMMITTER":"${{ inputs.committer }}","SIGNOFF":"${{ inputs.signoff }}","USE_GITSIGN":"${{ inputs.use-gitsign }}","CHANGED_FILES":"${{ steps.update_files.outputs.changed_files }}","WORKING_DIR":"${{ inputs.working-dir }}","STALE_TAGS_MD":"${{ steps.stale_tags.outputs.stale_tags_md }}"},"with":{"github-token":"${{ inputs.token }}","script":"const { execFileSync } = require('child_process');\n\ntry {\n  // Parse author and committer\n  const parseIdentity = (identity) =\u003e {\n    const match = identity.match(/^(.+?)\\s*\u003c(.+?)\u003e$/);\n    if (!match) throw new Error(`Invalid identity format: ${identity}`);\n    return { name: match[1].trim(), email: match[2].trim() };\n  };\n\n  const author = parseIdentity(process.env.AUTHOR);\n  const committer = parseIdentity(process.env.COMMITTER);\n  const prBranch = process.env.PR_BRANCH;\n  const changedFiles = process.env.CHANGED_FILES.split('\\n').filter(f =\u003e f.trim());\n\n  // Helper to run git commands\n  const git = (...args) =\u003e {\n    return execFileSync('git', args, { encoding: 'utf8' }).trim();\n  };\n\n  // Get base branch and create/reset PR branch\n  const baseBranch = git('branch', '--show-current');\n\n  let branchExists = false;\n  try {\n    git('rev-parse', '--verify', prBranch);\n    branchExists = true;\n  } catch (e) {}\n\n  if (branchExists) {\n    git('checkout', prBranch);\n    git('reset', '--hard', baseBranch);\n  } else {\n    git('checkout', '-b', prBranch);\n  }\n\n  // Stage changed files\n  for (const file of changedFiles) {\n    git('add', '--', file);\n  }\n\n  // Commit with proper author/committer\n  const commitArgs = ['commit', '-m', process.env.COMMIT_MESSAGE];\n  if (process.env.SIGNOFF === 'true') {\n    commitArgs.push('--signoff');\n  }\n\n  execFileSync('git', commitArgs, {\n    encoding: 'utf8',\n    env: {\n      ...process.env,\n      GIT_AUTHOR_NAME: author.name,\n      GIT_AUTHOR_EMAIL: author.email,\n      GIT_COMMITTER_NAME: committer.name,\n      GIT_COMMITTER_EMAIL: committer.email,\n    }\n  });\n\n  console.log(`Committed: ${git('rev-parse', 'HEAD')}`);\n\n  // Push branch\n  git('push', 'origin', prBranch, '--force');\n\n  // Check if PR already exists\n  const { owner, repo } = context.repo;\n  const allPRs = await github.rest.pulls.list({\n    owner,\n    repo,\n    head: `${owner}:${prBranch}`,\n    state: 'all'\n  });\n\n  const openPR = allPRs.data.find(pr =\u003e pr.state === 'open');\n  const closedPR = allPRs.data.find(pr =\u003e pr.state === 'closed');\n  const labels = process.env.PR_LABELS.split(/[,\\n]/).map(l =\u003e l.trim()).filter(l =\u003e l);\n\n  // Build PR body\n  const diffFence = '```';\n  const prBody = process.env.PR_BODY + '\\n\\n## Changes\\n\u003cdetails\u003e\\n\\n' +\n    diffFence + 'diff\\n' + process.env.PR_DIFF + '\\n' + diffFence + '\\n\\n\u003c/details\u003e' +\n    (process.env.STALE_TAGS_MD ? '\\n\\n## Stale tags\\n\\n' + process.env.STALE_TAGS_MD : '');\n\n  // Helper functions\n  const updatePR = async (prNumber) =\u003e {\n    await github.rest.pulls.update({\n      owner,\n      repo,\n      pull_number: prNumber,\n      title: process.env.PR_TITLE,\n      body: prBody\n    });\n  };\n\n  const addLabels = async (prNumber) =\u003e {\n    if (labels.length \u003e 0) {\n      await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels });\n    }\n  };\n\n  let prNumber;\n\n  if (openPR) {\n    // Update existing open PR\n    prNumber = openPR.number;\n    await updatePR(prNumber);\n  } else if (closedPR) {\n    // Closed PR exists (merged or just closed) - create a new PR instead of trying to reopen\n    console.log(`Found closed PR #${closedPR.number}, creating new PR instead`);\n    const { data: pr } = await github.rest.pulls.create({\n      owner,\n      repo,\n      head: prBranch,\n      base: baseBranch,\n      title: process.env.PR_TITLE,\n      body: prBody\n    });\n    prNumber = pr.number;\n  } else {\n    // No existing PR - create new one\n    const { data: pr } = await github.rest.pulls.create({\n      owner,\n      repo,\n      head: prBranch,\n      base: baseBranch,\n      title: process.env.PR_TITLE,\n      body: prBody\n    });\n    prNumber = pr.number;\n  }\n\n  // Add labels to PR\n  await addLabels(prNumber);\n\n  core.setOutput('pull_request_number', prNumber.toString());\n  console.log(`PR #${prNumber}`);\n\n} catch (error) {\n  core.setFailed(`Failed to create pull request: ${error.message}`);\n  console.error(error);\n}\n"}}]},"default_branch":"main","path":null},"repo_metadata":{"id":209623908,"uuid":"715324491","full_name":"chainguard-dev/digestabot","owner":"chainguard-dev","description":"A Github Action to automatically update digests for container images.","archived":false,"fork":false,"pushed_at":"2026-09-29T14:13:04.000Z","size":259,"stargazers_count":96,"open_issues_count":0,"forks_count":27,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-09-29T16:53:25.877Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chainguard-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2023-11-06T23:06:52.000Z","updated_at":"2026-09-29T14:21:07.000Z","dependencies_parsed_at":"2026-09-29T15:33:20.240Z","dependency_job_id":null,"html_url":"https://github.com/chainguard-dev/digestabot","commit_stats":null,"previous_names":["chainguard-dev/digestabot"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/chainguard-dev/digestabot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainguard-dev","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/sbom","scorecard":{"id":273020,"data":{"date":"2025-08-11","repo":{"name":"github.com/chainguard-dev/digestabot","commit":"dd76366ab0ec8d719d24fd242f743c0b3793c86e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":6.4,"checks":[{"name":"Maintained","score":0,"reason":"1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/check-readme.yaml:17","Info: found token with 'none' permissions: .github/workflows/check-readme.yaml:1","Warn: no topLevel permission defined: .github/workflows/test.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:   3 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   3 out of   3 third-party GitHubAction dependencies pinned","Info:   1 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":8,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: required approving review count is 1 on branch 'main'","Warn: codeowners review is not required on branch 'main'","Info: status check found to merge onto on branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/chainguard-dev/.github/SECURITY.md:1","Info: Found linked content: github.com/chainguard-dev/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/chainguard-dev/.github/SECURITY.md:1","Info: Found text in security policy: github.com/chainguard-dev/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T13:49:52.207Z","repository_id":209623908,"created_at":"2025-08-17T13:49:52.207Z","updated_at":"2025-08-17T13:49:52.207Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":343170754,"owners_count":38059585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-06T02:00:06.537Z","response_time":86,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"},"owner_record":{"login":"chainguard-dev","name":"Chainguard","uuid":"87436699","kind":"organization","description":"Making the software supply chain secure by default.","email":"interest@chainguard.dev","website":"https://chainguard.dev","location":"United States of America","twitter":"chainguard_dev","company":null,"icon_url":"https://avatars.githubusercontent.com/u/87436699?v=4","repositories_count":49,"last_synced_at":"2023-03-04T02:29:06.196Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/chainguard-dev","funding_links":[],"total_stars":null,"followers":null,"following":null,"created_at":"2022-11-14T08:19:45.466Z","updated_at":"2023-03-04T02:29:06.362Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainguard-dev","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainguard-dev/repositories"},"tags":[{"name":"v1.3.2","sha":"33d0b78e580aa0c83fe188eb3dfad6611b662479","kind":"commit","published_at":"2026-06-01T17:55:54.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.3.2","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.3.2","dependencies_parsed_at":"2026-08-08T06:16:51.569Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.3.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.3.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.3.2/manifests"},{"name":"v1.3.1","sha":"afe360aa3b0c29d88844138e8fa0349384398967","kind":"commit","published_at":"2026-03-27T15:33:44.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.3.1","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.3.1","dependencies_parsed_at":"2026-08-08T06:16:51.014Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.3.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.3.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.3.1/manifests"},{"name":"v1.3.0","sha":"286204ec689dec2f8acae04b6941cf5af8e5b215","kind":"commit","published_at":"2026-03-27T08:26:13.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.3.0","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.3.0","dependencies_parsed_at":"2026-08-08T06:16:50.927Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.3.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.3.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.3.0/manifests"},{"name":"v1.2.3","sha":"a3b776c1ca57d3127c85578cde8fef6eed3c75d3","kind":"commit","published_at":"2025-08-25T16:02:56.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.2.3","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.2.3","dependencies_parsed_at":"2025-10-16T08:14:11.372Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.2.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.3/manifests"},{"name":"v1","sha":"43222237fd8a07dc41a06ca13e931c95ce2cedac","kind":"tag","published_at":"2025-03-14T08:35:27.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1","dependencies_parsed_at":"2026-08-24T07:16:53.007Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1/manifests"},{"name":"v1.2.2","sha":"43222237fd8a07dc41a06ca13e931c95ce2cedac","kind":"commit","published_at":"2025-03-11T09:45:08.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.2.2","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.2.2","dependencies_parsed_at":"2025-12-12T15:02:24.907Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.2.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.2/manifests"},{"name":"v1.2.1","sha":"cee67ce333549107c469dbe7656afda5a1e1f287","kind":"tag","published_at":"2024-10-24T14:42:07.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.2.1","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.2.1","dependencies_parsed_at":"2025-12-12T15:02:24.908Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.2.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.1/manifests"},{"name":"v1.2.0","sha":"02ea60d2aeb26664ace4a9cc2ecdbea96888aaa4","kind":"commit","published_at":"2024-08-08T12:51:28.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.2.0","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.2.0","dependencies_parsed_at":"2025-12-12T15:02:24.907Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.2.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.2.0/manifests"},{"name":"v1.1.0","sha":"7dc10a1f7fb063b5130b1116f26a5a0880c2a00f","kind":"tag","published_at":"2024-06-11T15:29:39.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.1.0","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.1.0","dependencies_parsed_at":"2025-12-12T15:02:24.916Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.1.0/manifests"},{"name":"v1.0.3","sha":"3830b931642989ef391e6db4c0bbcd2bc20d064f","kind":"commit","published_at":"2024-02-28T17:59:44.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.0.3","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.0.3","dependencies_parsed_at":"2025-12-12T15:02:24.914Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.0.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.3/manifests"},{"name":"v1.0.2","sha":"4298e530896fb4164f9c89030c561b75b9321149","kind":"commit","published_at":"2023-12-13T18:33:52.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.0.2","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.0.2","dependencies_parsed_at":"2025-12-12T15:02:25.184Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.0.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.2/manifests"},{"name":"v1.0.1","sha":"6d454c6445262c5fa4a8b34ae39762e5668b1c27","kind":"commit","published_at":"2023-12-07T21:01:25.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.0.1","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.0.1","dependencies_parsed_at":"2025-12-12T15:02:25.889Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.0.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.1/manifests"},{"name":"v1.0.0","sha":"a5e3ca45fa4a677554a5b61c08bb4efb16384b22","kind":"commit","published_at":"2023-11-07T16:24:54.000Z","download_url":"https://codeload.github.com/chainguard-dev/digestabot/tar.gz/v1.0.0","html_url":"https://github.com/chainguard-dev/digestabot/releases/tag/v1.0.0","dependencies_parsed_at":"2025-12-12T15:02:26.868Z","dependency_job_id":null,"purl":"pkg:github/chainguard-dev/digestabot@v1.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/tags/v1.0.0/manifests"}]},"repo_metadata_updated_at":"2026-10-06T02:07:29.838Z","dependent_packages_count":0,"downloads":null,"downloads_period":null,"dependent_repos_count":0,"rankings":{"downloads":null,"dependent_repos_count":28.754133133695177,"dependent_packages_count":0.0,"stargazers_count":null,"forks_count":null,"docker_downloads_count":null,"average":14.377066566847589},"purl":"pkg:githubactions/chainguard-dev/digestabot","advisories":[],"docker_usage_url":"https://docker.ecosyste.ms/usage/actions/chainguard-dev/digestabot","docker_dependents_count":null,"docker_downloads_count":null,"usage_url":"https://repos.ecosyste.ms/usage/actions/chainguard-dev/digestabot","dependent_repositories_url":"https://repos.ecosyste.ms/api/v1/usage/actions/chainguard-dev/digestabot/dependencies","status":null,"funding_links":[],"critical":null,"issue_metadata":{"last_synced_at":"2026-10-06T02:07:29.611Z","issues_count":12,"pull_requests_count":89,"avg_time_to_close_issue":1864556.6666666667,"avg_time_to_close_pull_request":1178289.8378378379,"issues_closed_count":3,"pull_requests_closed_count":74,"pull_request_authors_count":15,"issue_authors_count":9,"avg_comments_per_issue":0.3333333333333333,"avg_comments_per_pull_request":0.15730337078651685,"merged_pull_requests_count":66,"bot_issues_count":0,"bot_pull_requests_count":55,"past_year_issues_count":0,"past_year_pull_requests_count":12,"past_year_avg_time_to_close_issue":null,"past_year_avg_time_to_close_pull_request":323950.3333333333,"past_year_issues_closed_count":0,"past_year_pull_requests_closed_count":9,"past_year_pull_request_authors_count":1,"past_year_issue_authors_count":0,"past_year_avg_comments_per_issue":null,"past_year_avg_comments_per_pull_request":0.16666666666666666,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":12,"past_year_merged_pull_requests_count":7,"issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fdigestabot/issues","maintainers":[{"login":"cpanato","count":10,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/cpanato"},{"login":"priyawadhwa","count":2,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/priyawadhwa"},{"login":"jdolitsky","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/jdolitsky"}],"active_maintainers":[]},"versions_url":"https://packages.ecosyste.ms/api/v1/registries/github%20actions/packages/chainguard-dev%2Fdigestabot/versions","version_numbers_url":"https://packages.ecosyste.ms/api/v1/registries/github%20actions/packages/chainguard-dev%2Fdigestabot/version_numbers","latest_version_url":"https://packages.ecosyste.ms/api/v1/registries/github%20actions/packages/chainguard-dev%2Fdigestabot/latest_version","dependent_packages_url":"https://packages.ecosyste.ms/api/v1/registries/github%20actions/packages/chainguard-dev%2Fdigestabot/dependent_packages","related_packages_url":"https://packages.ecosyste.ms/api/v1/registries/github%20actions/packages/chainguard-dev%2Fdigestabot/related_packages","codemeta_url":"https://packages.ecosyste.ms/api/v1/registries/github%20actions/packages/chainguard-dev%2Fdigestabot/codemeta","maintainers":[]}