Repository Archiving & Unarchiving with GitHub GRAPHQL API

~ 5 minutes read
no time? jump straight to the conclusion

Archiving a GitHub repository via GitHub REST API is possible. However you can unarchive a GitHub repository only with the GraphQL GitHub API. Graphql.org is a good starting point to read about graphql.
This write up is about how to archive and unarchive GitHub Repositories via the GraphQL GitHub API. You’ll learn about graphql differences between the GraphQL explorer and the GraphQL GitHub API with curl.

Why? 

I had to test code that archives a repository using the GitHub REST API. The only way to revert the repository archiving is GitHub’s GraphQL unarchive functionality. Deleting and recreating the repository wasn’t an option for me.

There are two main options to use the GitHub GraphQL API:

  • GraphQL explorer
  • GraphQL API within the programming language of your choice – I choose shell scripts with curl for this write up

GraphQL Explorer

Archiving a repository using the GraphQL Explorer requires identifying the repository id first. 

query FindRepoID {
    repository(owner:"[github user or org]", name:"[repository]"){
        id,
        isArchived,
    }
}

source

The graphql query above does not only return the repository ID, also it contains information about the repository being archived already. Let’s use this repository ID in a graphql mutation to archive the identified repository:

mutation ArchiveRepository {
    archiveRepository(input:{clientMutationId:"true",repositoryId:"[repositoryID]"}) {
        repository {
            isArchived,
            description,
        }
    }
}

source

graphql explorer
graphql explorer

Unarchiving a repository in the GraphQL Explorer is very similar:

mutation UnArchiveRepository {
    unarchiveRepository(input:{clientMutationId:"true",repositoryId:"[insert ID]"}) {
        repository {
            isArchived,
            description
        }
    }
}

source

While this is straightforward, it is not too obvious to convert the queries and mutation to graphql code that works with curl.
This is because the test code I had to write could not utilize the GraphQL Explorer web frontend.

GraphQL API in curl

A GraphQL query that works with curl or other programming languages needs a query key within the graphql file. The main differences in graphql code for GitHub GraphQL API and the GraphQL Explorer are red and bold.

findRepoID.graphql file

{
    "query": "query ($org: String!, $repo: String!) {repository(owner: $org, name: $repo) { id isArchived }  }",
    "variables": {
        "org": "[github user or org]",
        "repo": "[repository]"
    }
}

source

Call the GraphQL API with curl:

curl -H "Authorization: bearer [github personal access token]" -X POST -H "Content-Type: application/json" -d @findRepoID.graphql https://api.github.com/graphql

Secrets should be referenced as an environment variable: “Authorization bearer: $GH_ACCESS_TOKEN“, otherwise they will end up in the terminal history.

The GitHub access token in the Authorization header shall have full control of the repository.

personal access token repository scope

The GraphQL API would answer with

{"data":{"repository":{"id":"[SampleRepoID]","isArchived":false}}}

Let’s use the returned ID in the archiveRepository.graphql file below If the repository is not archived:

{
    "query": "mutation ArchiveRepository ($mutationId: String!, $repoID: String!) {archiveRepository(input:{clientMutationId:$mutationId, repositoryId:$repoID}) {repository { isArchived, description } } }",
    "variables": {
        "mutationId": "true",
        "repoID": "[repo id]"
    }
}

source

The main difference in graphql code for GitHub GraphQL API and the GraphQL Explorer is the query key, although the actual call is a GraphQL mutation and not a GraphQL query.

Call the GraphQL API with curl:

curl -H "Authorization: bearer [github personal access token]" -X POST -H "Content-Type: application/json" -d @archiveRepository.graphql https://api.github.com/graphql

The answer would be:

{"data":{"archiveRepository":{"repository":{"isArchived":true,"description":"test repository"}}}}

Unarchiving is straight forward:

{
    "query": "mutation UnArchiveRepository ($mutationId: String!, $repoID: String!) {unarchiveRepository(input:{clientMutationId:$mutationId, repositoryId:$repoID}) {repository { isArchived, description } } }",
    "variables": {
        "mutationId": "true",
        "repoID": "[repo id]"
    }
}

source

The main difference in Graphql code for GitHub GraphQL API and the GraphQL Explorer is the query key – the same as in the archiveRepository.graphql example.

Call the GraphQL API with curl:

curl -H "Authorization: bearer [github personal access token]" -X POST -H "Content-Type: application/json" -d @unarchiveRepository.graphql https://api.github.com/graphql

and fetch the answer

{"data":{"unarchiveRepository":{"repository":{"isArchived":false,"description":"test repository"}}}}

Fetch Repository ID via GitHub CLI

You can also fetch a repository ID with the GitHub CLI. You would use a file like findRepoID_gh_cli.graphql:

query FindRepoID($name: String!, $owner: String!) {
    repository(owner: $owner, name: $name) {
        id,
        isArchived
    }
}

source

Use this file with the GitHub CLI in your terminal:

gh api graphql -F owner='[github user or organization]' -F name='[repository]' -f query="$(cat ./findRepoID_gh_cli.graphql)" | jq '.data.repository.id'

There are 2 important notes I want you to be aware of:

  1. Use the same syntax as you would use in the GraphQL Explorer in GitHub CLI requests with graphql data.
  2. Make sure the GitHub CLI is installed as well as jq

Conclusion

The main difference between GraphQL explorer and the GraphQL API (https://api.github.com/graphql) is:

The GraphQL explorer does not need a query key regardless of using graphql queries or graphql mutations.

In contrast, the GraphQL API requires a query key for both queries and mutations.


Archiving and Unarchiving GitHub repositories is only possible using GraphQL GitHub API only: 

Code

Find all code snippets above combined in one gist: Repository Archiving & Unarchiving with GitHub GraphQL API.

Be the first to comment

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.