Github Package Registry에 push 한 이미지를 삭제하는 방법

결론



결론부터 먼저 쓰면 public 리포지토리의 경우는 한 번 push 한 이미지는 스스로 삭제할 수 없다!
어째서 가지고 있을 경우는 여기 작성한 양식 로부터 안의 사람에게 부탁할 수밖에 없는 것 같다…

우선 부탁은 했다. 결과는 추후 추기 예정.

양식의 부탁으로부터 약 1주일. 삭제했기 때문에 연락했습니다! !

제대로 사라졌다 !

시작



Github Package Registry가 어느새 사용할 수 있게 되었으므로 조속히 적당한 이미지를 push 해 보자!

할 수 있었어!
응? ansible ?



아...아아아, typo 하고ーーーーー! !
우선 삭제다-! 라고 이것 어떻게 삭제하면 좋을까? 라는 것으로 삭제하려고 생각했지만 아무래도 삭제적인 메뉴를 찾을 수 없고. docker의 부속 명령에도 그런 것은 없고, 어때? 어떻게 해야 하나요? 라고 일로 조사 시작하면 이외에도 힘들었다.

GraphQL로 열심히 해본 궤적…



우선 사용하는 API는 Github GraphQL 로 deletePackageVersion 라는 mutation 을 사용하면 좋을 것 같다.

그러나 어떻게 두드리면 좋을지 모르기 때문에 구구한다…. 그리고 문서의 input 이나 returns 필드의 사양을 참조하면서 이하와 같은 쿼리를 던지면 좋을 것 같다는 것을 알 수 있다.
curl -sL -XPOST https://api.github.com/graphql \
  -H "Authorization: bearer $TOKEN" \
  -H 'Accept: application/vnd.github.package-deletes-preview+json' \
  -d '{"query":"mutation{deletePackageVersion(input:{clientMutationId: \"1\",packageVersionId:\"XXXXX\"}){clientMutationId,success}}"}'

이해하기 어렵기 때문에 쓰면 POST 한 JSON의 query 값과 GraphQL과 응답은 다음과 같습니다.
input에 지정하는 값이 무엇인지 잘 모르기 때문에 적당히 입력하고 있기 때문에 화내고 있다. 덧붙여서 clientMutationId 는 무엇이든 좋을 것 같다 (어쩌면 리퀘스트와 리스폰스의 결부용으로 이용자적으로 일의적인 값을 건네줄 수 있는 녀석으로 따로 같아도 움직인다)이지만, packageVersionId 에 지정해야 할 값이 무엇인가 잘 분으로부터 아니... 우선 적당히 던져 본다.
mutation {
  deletePackageVersion(
    input:{
      clientMutationId: "1",
      packageVersionId: "XXXXX"
    }
  )
  {
    clientMutationId,
    success
  }
}

↑GraphQL의 쿼리 ↓응답
{
  "data": {
    "deletePackageVersion": null
  },
  "errors": [
    {
      "type": "NOT_FOUND",
      "path": [
        "deletePackageVersion"
      ],
      "locations": [
        {
          "line": 1,
          "column": 10
        }
      ],
      "message": "Could not resolve to a node with the global id of 'XXXXX'"
    }
  ]
}

우선 이 의미를 아는 message 주의를 되찾아 packageVersionId 를 생각한다. 우선 latest 라든지 ansibke:latest 라든지 kawaz/docker-ansible/ansibke:latest 라든지 생각해 내는 한의 값을 넣어 보지만 모두 404 가 돌아온다…
다시 한번 packageVersionId 의 형태인 다른 D 의 문서를 보면 base64 인코딩된 독특한 값인 것 같다. 미안해. 그렇다면 이것은 먼저 GET 계열의 쿼리를 던져 내부 ID 같은 것을 찾을 필요가 있잖아요? 하는 것으로 패키지 일람을 취득하는 API를 찾는 여행에 나간다.

1시간 정도 문서 읽거나 API 시험하거나 하면서 점차 알았다… 응답에 갖고 싶은 필드를 전부 조사해 열거해 주지 않으면 어쩐지 너무 지나치게… 일로 돈.
curl -sL -X POST https://api.github.com/graphql \
  -H "Authorization: bearer $TOKEN" \
  -d '{"query":"query{repository(owner:\"kawaz\",name:\"docker-ansible\"){registryPackages(first:10){nodes{packageType,registryPackageType,name,nameWithOwner,
id,versions(first:10){nodes{id,version,readme}}}}}}"}'
query {
  repository(owner:"kawaz", name:"docker-ansible") {
    registryPackages(first:10) {
      nodes {
        packageType,
        registryPackageType,
        name,
        nameWithOwner,
        id,
        versions(first:10) {
          nodes{
            id,
            version,
            readme
          }
        }
      }
    }
  }
}

↑GraphQL의 쿼리 ↓응답
{
  "data": {
    "repository": {
      "registryPackages": {
        "nodes": [
          {
            "packageType": "DOCKER",
            "registryPackageType": "docker",
            "name": "ansibke",
            "nameWithOwner": "kawaz/ansibke",
            "id": "MDE1OlJlZ2lzdHJ5UGFja2FnZTQxNDM3",
            "versions": {
              "nodes": [
                {
                  "id": "MDIyOlJlZ2lzdHJ5UGFja2FnZVZlcnNpb24xNzc3MTY=",
                  "version": "docker-base-layer",
                  "readme": "あああ。。。イメージ名 typo しとる…。"
                }
              ]
            }
          },
          {
            "packageType": "DOCKER",
            "registryPackageType": "docker",
            "name": "ansible",
            "nameWithOwner": "kawaz/ansible",
            "id": "MDE1OlJlZ2lzdHJ5UGFja2FnZTQxNDQw",
            "versions": {
              "nodes": [
                {
                  "id": "MDIyOlJlZ2lzdHJ5UGFja2FnZVZlcnNpb24xNzc3MzA=",
                  "version": "latest",
                  "readme": null
                },
                {
                  "id": "MDIyOlJlZ2lzdHJ5UGFja2FnZVZlcnNpb24xNzc3Mjk=",
                  "version": "2.8.4",
                  "readme": null
                },
                {
                  "id": "MDIyOlJlZ2lzdHJ5UGFja2FnZVZlcnNpb24xNzc3Mjc=",
                  "version": "docker-base-layer",
                  "readme": null
                }
              ]
            }
          }
        ]
      }
    }
  }
}

아-모-, GraphQL 귀찮게--! ! 그래서 겨우 원했던 ID 같은 것이 나왔다. 그래서 첫 번째 삭제 쿼리에 흠뻑 봐!
curl -sL -XPOST https://api.github.com/graphql \
  -H "Authorization: bearer $TOKEN" \
  -H 'Accept: application/vnd.github.package-deletes-preview+json' \
  -d '{"query":"mutation{deletePackageVersion(input:{clientMutationId: \"1\",packageVersionId:\"MDIyOlJlZ2lzdHJ5UGFja2FnZVZlcnNpb24xNzc3MTY=\"}){clientMutationId,success}}"}'

그래서 결국 삭제 쿼리 응답의 형태가 바뀌었다! 이거 이긴다! ? ? ? …네 그래 그래—.
{
  "data": {
    "deletePackageVersion": null
  },
  "errors": [
    {
      "type": "UNPROCESSABLE",
      "path": [
        "deletePackageVersion"
      ],
      "locations": [
        {
          "line": 1,
          "column": 11
        }
      ],
      "message": "Public package versions are not eligible for deletion. For more on our deletion policy, see https://help.github.com/articles/about-github-package-registry/#deleting-a-package."
    }
  ]
}

요약 「퍼블릭 패키지는 정책적으로 삭제하지 않기로 하고 있어, 어째서라고 한다면.. !

뭐, 이번 작업으로 GraphQL의 감각을 왠지 이해할 수 있었으므로 좋다고 하자….

좋은 웹페이지 즐겨찾기