19

Question: How can I make a package "disappear" from Github Package Registry?

  • Documentation says: You cannot "delete" but a package "disappears" when all versions are removed.

Background:

  • A typo in the Gradle publish task resulted in the release of packages which should not be published.

Steps so far:

  • I did not find a "delete" option on the Github Web App.
  • I tried to delete via the GraphQL API of Github but I need a package ID for this command:
curl -X POST \
-H "Accept: application/vnd.github.package-deletes-preview+json" \
-H "Authorization: bearer ACCESS_TOKEN" \
-d '{"query":"mutation { deletePackageVersion(input:{packageVersionId:\"PACKAGE_ID==\"}) { success }}"}' \
https://api.github.com/graphql
  • I did not find the full packageVersionId on the Github Web App.
  • I tried to query the API for the Package IDs but failed to form a valid query:
curl -X POST \
-H "Accept: application/vnd.github.package-deletes-preview+json" \
-H "Authorization: bearer ACCESS_TOKEN" \
-d "query {
  organization(login: "ORGANIZATION_ACCOUNT") {
    registryPackages {
      edges {
        node {
          name
          id
        }
      }
    }
  }
}" \
https://api.github.com/graphql

# The API returns:
{
  "message": "Problems parsing JSON",
  "documentation_url": "https://developer.github.com/v4"
}
  • I tried to use the GraphQL API Explorer but I the automatically set up token misses the sufficient rights:
# See query above - the API returns via the Explorer:
{
  "errors": [
    {
      "type": "INSUFFICIENT_SCOPES",
      "locations": [
        {
          "line": 6,
          "column": 11
        }
      ],
      "message": "Your token has not been granted the required scopes to execute this query. The 'name' field requires one of the following scopes: ['read:packages'], but your token has only been granted the: ['read:gpg_key', 'read:org', 'read:public_key', 'read:repo_hook', 'repo', 'user'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens."
    },
    {
      "type": "INSUFFICIENT_SCOPES",
      "locations": [
        {
          "line": 7,
          "column": 11
        }
      ],
      "message": "Your token has not been granted the required scopes to execute this query. The 'id' field requires one of the following scopes: ['read:packages'], but your token has only been granted the: ['read:gpg_key', 'read:org', 'read:public_key', 'read:repo_hook', 'repo', 'user'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens."
    }
  ]
}
  • I did not find an option on the Explorer Web App to set another access token.

Desired Solution

  • I like to know if there is a simpler way to do this and if not, how to get the packageVersionIds required to un-link the packages so that they disappear.

Update1: It's about packages published to a public repository.

hb0
  • 3,350
  • 3
  • 30
  • 48

5 Answers5

30

Removing a package from a public registry is not allowed, however you can remove a version of a package from a private registry as mentioned in GitHub docs:

Now it is available to delete on GitHub directly:

  1. On GitHub, navigate to the main page of the repository.
  2. To the right of the list of files, click Packages.
  3. Click the name of the package that you want to delete.
  4. On the right, use the Edit package drop-down and select "Manage versions".
  5. To the right of the version you want to delete, click Delete.
  6. To confirm deletion, type the package name and click I understand the consequences, delete this version.

GraphQL was the only method for this purpose in the past:

$ curl -X POST https://api.github.com/graphql \
-H "Accept: application/vnd.github.package-deletes-preview+json" \
-H "Authorization: bearer <github_token>" \
-d '{"query":"mutation { deletePackageVersion(input:{packageVersionId:\"MDE0OlBhY2thZ2VWZXJzaW9uMzc5MTE0kFcA\"}) { success }}"}'

Version id of GitHub packages can be listed as follows:

$ curl -sL -X POST https://api.github.com/graphql \
-H "Authorization: bearer <github_token>" \
-d '{"query":"query{repository(owner:\"<repo_owner>\",name:\"<repo_name>\"){packages(first:10){nodes{packageType,name,id,versions(first:10){nodes{id,version,readme}}}}}}"}' | jq .

Update the parameters below with yours:

  • <github_token>
  • <repo_owner>
  • <repo_name>

It returns as follows:

{
  "data": {
    "repository": {
      "registryPackages": {
        "nodes": [
          {
            "packageType": "DOCKER",
            "registryPackageType": "docker",
            "name": "demo_image_1",
            "nameWithOwner": "aki***/demo_image_1",
            "id": "MDc6UGFja2FnZTYzNjg3AkFc",
            "versions": {
              "nodes": [
                {
                  "id": "MDE0OlBhY2thZ2VWZXJzaW9uMzc5MTE0kFcA",
                  "version": "0.1a",
                  "readme": null
                },
                {
                  "id": "MDE0OlBhY2thZ2VWZXJzaW9uMzYzNTY2FcAk",
                  "version": "0.1",
                  "readme": null
                },
                {
                  "id": "MDE0OlBhY2thZ2VWZXJzaW9uMzYzNTY0cAkF",
                  "version": "docker-base-layer",
                  "readme": null
                }
              ]
            }
          },
        ]
      }
    }
  }
Akif
  • 6,018
  • 3
  • 41
  • 44
  • 1
    I up-voted your answer as this works for private packages and I missed to state in the question that it's about public packages. Thanks for your input on how to GET the IDs of the package versions! – hb0 Dec 03 '19 at 10:44
  • Private packages cannot be listed with a token which only has the `read:packages` permission. The following permissions were sufficient: `read:packages, repo, write:packages` – hb0 Dec 03 '19 at 11:06
  • 1
    I updated my answer to clarify that delete of package from public registry is not allowed by GitHub. – Akif Dec 06 '19 at 04:04
  • Hello, could you take a look at my question? https://stackoverflow.com/questions/59559176/github-package-registry-how-to-delete-a-version I tried your curl method but I keep getting Problems parsing json – JianYA Jan 02 '20 at 06:39
  • Be aware that this still doesn't work for docker images, it returns : `"Version deletion is currently unsupported for docker. For more on our deletion policy, see https://help.github.com/articles/about-github-package-registry/#deleting-a-package."`, which actually doesn't mention any caveats about Docker. Weird. – Omar Feb 14 '20 at 10:57
14

Package versions of a private can be delete by the maintainer:

  • Via the Github API, see the answer of @Akif
  • Via the Github Support
  • Via the Web App Github.com
    • Go to your repositories' packages https://github.com/orgs/YOUR_ACCOUNT/packages?repo_name=YOUR_REPO

    • Select one package https://github.com/YOUR_ACCOUNT/YOUR_REPO/packages/PACKAGE_ID

    • Show all versions of that package https://github.com/cyface-de/backend/packages/81398/versions

    • Use the DELETE button to delete this private package

      enter image description here

Package versions of a public repository cannot be deleted by the maintainer, i.e.:

  • The Github support needs to be contacted to have a package or version removed.

  • Workaround: make your repository temporarily private for the deletion:

    • Attention: This results into loss of stars, etc., see Github Warning!
    • Repository Settings > Danger Zone > Make private
    • To delete the package versions:
      • via API: Follow instructions by @Akif's answer
      • via the Web-App: see above
    • Repository Settings > Danger Zone > Make public
hb0
  • 3,350
  • 3
  • 30
  • 48
  • I find it fascinating that this workaround exists, yet GitHub disallows deleting packages from public repos. What sense does that make? The only people who are actually affected by this seems to be people with forked repos - making them unable to delete any packages they upload to their fork or having to resort to deleting their fork – smac89 Apr 18 '20 at 17:11
  • 1
    Just a guess: This could be security related: Image a very important public package on which many other apps rely on. When you import this package version X you can check the code base to ensure there are no security issues. If the package owner can just delete and replace the **same version** with another build which contains a malfunction the apps who use this package version would not notice that the build behind the version changed. The same applies when you remove and replace a full package instead of just one version. – hb0 Apr 19 '20 at 10:41
  • But by forcing the repository owner to make the repository private and public again the repository looses all its stars, etc. and by that the other apps which rely on that package/version might get a notice and know that they can no longer assume the package/version they used before is still the same code/build. I Don't want to start a discussion, this is just a possible explanation. For more details best ask the Github support or community forum. – hb0 Apr 19 '20 at 10:43
7

I found a solution how to remove the package.

  1. Go to the repository settings and change the visibility to "private".
  2. Go to the repository, click on "packages" >> "Manage versions"
  3. On the page we see the "delete" button.
  4. After deleting, return to the repository settings and change the visibility to "public".
  5. Profit!
1

While testing (private packages), I had published the same version multiple times and deleted it. Until a point where it somehow stuck and I was unable to click "Manage Versions" on the UI as the button changed to "Package Settings" instead. Previously provided GraphQL did not help, but I was able to identify the versions on GraphQL Explorer with the following:

query {
  repository(owner: "<org>", name: "<repo>") {
    packages(first: 10) {
      edges {
        node {
          latestVersion {
            id
            version
          }
        }
      }
    }
  }
}

This has returned a slightly out of sync list of nodes similar to:

{
  "data": {
    "repository": {
      "packages": {
        "edges": [
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": null
            }
          },
          {
            "node": {
              "latestVersion": {
                "id": "MDE0OlBhY2thZ2VWZXJzaW9uNTYxMjQyOQ=="
                "version": "0.1.0"
              }
            }
          }
        ]
      }
    }
  }
}

With this, I was able to delete them one by one with:

curl -X POST https://api.github.com/graphql \
-H "Accept: application/vnd.github.package-deletes-preview+json" \
-H "Authorization: bearer $TOKEN" \
-d '{"query":"mutation { deletePackageVersion(input:{packageVersionId:\"MDE0OlBhY2thZ2VWZXJzaW9uNTYxMjQyOQ==\"}) { success }}"}'
Anton Yurchenko
  • 540
  • 4
  • 5
0

list all packages for user

https://docs.github.com/en/rest/packages#list-packages-for-the-authenticated-users-namespace

$ curl -H "Authorization: token <token>" \
    https://api.github.com/users/zhangguanzhang/packages?package_type=container
[
  {
    "id": 1539801,
    "name": "xxx",
    "package_type": "container",
...
]

list all the tags

https://docs.github.com/en/rest/packages#get-all-package-versions-for-a-package-owned-by-the-authenticated-user

$ curl -H "Authorization: token <token>" \
    https://api.github.com/user/packages/container/xxx/versions
[
  {
    "id": 28992295,
    "name": "sha256:d371657a4f661a854ff050898003f4cb6c7f36d968a943c1d5cde0952bd93c80",
    "url": "https://api.github.com/users/zhangguanzhang/packages/container/xxx/versions/28992295",
    "package_html_url": "https://github.com/users/zhangguanzhang/packages/container/package/xxx",
    "created_at": "2022-07-20T05:02:49Z",
    "updated_at": "2022-07-20T05:02:49Z",
    "html_url": "xxx",
    "metadata": {
      "package_type": "container",
      "container": {
        "tags": [
          "test2"
        ]
      }
    }
  },
  {
    "id": 28992004,
    "name": "sha256:efc09388b15fb423c402f0b8b28ca70c7fd20fe31f8d7531ae1896bbb4944999",
    "url": "xxx",
    "package_html_url": "https://github.com/users/zhangguanzhang/packages/container/package/xxx",
    "created_at": "2022-07-20T04:55:14Z",
    "updated_at": "2022-07-20T04:55:14Z",
    "html_url": "xxx",
    "metadata": {
      "package_type": "container",
      "container": {
        "tags": [
          "test1",
          "latest"
        ]
      }
    }
  }
]

delete a tag

https://docs.github.com/en/rest/packages#delete-a-package-version-for-the-authenticated-user

curl -X DELETE -H "Authorization: token <token>" \
    https://api.github.com/user/packages/container/xxx/versions/28992295

used the jq to get the versionID:

curl -H "Authorization: token <token>" \
     https://api.github.com/user/packages/container/xxx/versions | \
  jq '.[]|select(.metadata.container.tags[]=="test2")|.id'
张馆长
  • 1,321
  • 10
  • 11