aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/pkgs/applications/networking/cluster/terraform-providers/update-all
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p bash coreutils jq nix gitAndTools.hub
# vim: ft=sh sw=2 et
# shellcheck shell=bash
#
# This scripts scans the github terraform-providers repo for new releases,
# generates the corresponding nix code and finally generates an index of
# all the providers given in ./providers.txt.
set -euo pipefail

# the maximum number of attempts before giving up inside of GET and prefetch_github
readonly maxAttempts=30

get_tf_providers_org() {
  # returns all terraform providers in a given organization, and their the
  # latest tags, in the format
  # $org/$repo $rev
  local org=$1
  hub api --paginate graphql -f query="
    query(\$endCursor: String) {
      repositoryOwner(login: \"${org}\") {
        repositories(first: 100, after: \$endCursor) {
          nodes {
            nameWithOwner
            name
            refs(first: 1, refPrefix: \"refs/tags/\", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {
              nodes {
                name
              }
            }
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
  }" | \
  jq -r '.data.repositoryOwner.repositories.nodes[] | select(.name | startswith("terraform-provider-")) | select((.refs.nodes | length) > 0) | .nameWithOwner + " " + .refs.nodes[0].name'
  # filter the result with jq:
  # - repos need to start with `teraform-provider-`
  # - they need to have at least one tag
  # for each of the remaining repos, assemble a string $org/$repo $rev
}

get_latest_repo_tag() {
  # of a given repo and owner, retrieve the latest tag
  local owner=$1
  local repo=$2
  hub api --paginate "https://api.github.com/repos/$owner/$repo/git/refs/tags" | \
    jq -r '.[].ref' | \
    grep -v 'v\.' | \
    cut -d '/' -f 3- | \
    sort --version-sort | \
    tail -1
}

prefetch_github() {
  # of a given owner, repo and rev, fetch the tarball and return the output of
  # `nix-prefetch-url`
  local owner=$1
  local repo=$2
  local rev=$3
  local retry=1
  while ! nix-prefetch-url --unpack "https://github.com/$owner/$repo/archive/$rev.tar.gz"; do
    echo "The nix-prefetch-url command has failed. Attempt $retry/${maxAttempts}" >&2
    if [[ "${retry}" -eq "${maxAttempts}" ]]; then
      exit 1
    fi
    retry=$(( retry + 1 ))
    sleep 5
  done
}

echo_entry() {
  local owner=$1
  local repo=$2
  local rev=$3
  local version=${rev#v}
  local sha256=$4
  cat <<EOF
{
  owner   = "$owner";
  repo    = "$repo";
  rev     = "$rev";
  version = "$version";
  sha256  = "$sha256";
};
EOF
}

indent() { sed 's/^/    /'; }

add_provider() {
  org="${1}"
  repo="${2}"
  rev="${3}"

  echo "*** $org/$repo $rev ***"
  name=$(echo "$repo" | cut -d - -f 3-)
  sha256=$(prefetch_github "$org" "$repo" "$rev")

  {
    echo "  $name ="
    echo_entry "$org" "$repo" "$rev" "$sha256" | indent
  } >> data.nix
}

## Main ##

cd "$(dirname "$0")"

# individual repos to fetch
slugs=(
  IBM-Cloud/terraform-provider-ibm
  ajbosco/terraform-provider-segment
  camptocamp/terraform-provider-pass
  carlpett/terraform-provider-sops
  poseidon/terraform-provider-matchbox
  poseidon/terraform-provider-ct
  tweag/terraform-provider-nixos
  tweag/terraform-provider-secret
)

# a list of providers to ignore
blacklist=(
  terraform-providers/terraform-provider-azure-classic
  terraform-providers/terraform-provider-cidr
  terraform-providers/terraform-provider-circonus
  terraform-providers/terraform-provider-cloudinit
  terraform-providers/terraform-provider-quorum
  hashicorp/terraform-provider-time
  terraform-providers/terraform-provider-vmc
)

cat <<HEADER > data.nix
# Generated with ./update-all
{
HEADER

# assemble list of terraform providers
providers=$(get_tf_providers_org "terraform-providers")
providers=$(echo "$providers";get_tf_providers_org "hashicorp")

# add terraform-providers from slugs
for slug in "${slugs[@]}"; do
  # retrieve latest tag
  org=${slug%/*}
  repo=${slug#*/}
  rev=$(get_latest_repo_tag "$org" "$repo")

  # add to list
  providers=$(echo "$providers";echo "$org/$repo $rev")
done

# filter out all providers on the blacklist
for repo in "${blacklist[@]}"; do
  providers=$(echo "$providers" | grep -v "^${repo} ")
done

# sort results alphabetically by repo name
providers=$(echo "$providers" | sort -t "/" --key=2)

# render list
IFS=$'\n'
for provider in $providers; do
  org=$(echo "$provider" | cut -d " " -f 1 | cut -d "/" -f1)
  repo=$(echo "$provider" | cut -d " " -f 1 | cut -d "/" -f2)
  rev=$(echo "$provider" | cut -d " " -f 2)
  add_provider "${org}" "${repo}" "${rev}"
done

cat <<FOOTER >> data.nix
}
FOOTER

echo Done.