I would like to use GitHub repository for posts in my Gatsby site. Right now I'm using two queries, first to get the names of the files:
{
viewer {
repository(name: "repository-name") {
object(expression: "master:") {
id
... on Tree {
entries {
name
}
}
}
pushedAt
}
}
}
And the second to get the contents of the files:
{
viewer {
repository(name: "repository-name") {
object(expression: "master:file.md") {
... on Blob {
text
}
}
}
}
}
Is there any way to get information about when each file was created and last updated with GraphQL? Right now I can get only pushedAt
for the whole repository and not individual files.
You can use the following query to get the file content and at the same time getting the last commit for this file. This way you also get the fields pushedAt
, committedDate
and authorDate
depending on what you need :
{
repository(owner: "torvalds", name: "linux") {
content: object(expression: "master:Makefile") {
... on Blob {
text
}
}
info: ref(qualifiedName: "master") {
target {
... on Commit {
history(first: 1, path: "Makefile") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
pageInfo {
endCursor
}
totalCount
}
}
}
}
}
}
Note that we need to also get the endCursor
field in order to get the first commit on the file (to get the file creation date)
For instance on the Linux repo, for the Makefile
file it gives:
"pageInfo": {
"endCursor": "b29482fde649c72441d5478a4ea2c52c56d97a5e 0"
}
"totalCount": 1806
So there are 1806 commit for this file
In order to get the first commit, a query referencing the last cursor which would be b29482fde649c72441d5478a4ea2c52c56d97a5e 1804
:
{
repository(owner: "torvalds", name: "linux") {
info: ref(qualifiedName: "master") {
target {
... on Commit {
history(first: 1, after:"b29482fde649c72441d5478a4ea2c52c56d97a5e 1804", path: "Makefile") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
}
}
}
}
}
}
which returns the first commit of this file.
I don't have any source about the cursor string format "b29482fde649c72441d5478a4ea2c52c56d97a5e 1804"
, I've tested with some other repositories with files with more than 1000 commits and it seems that it's always formatted like :
<static hash> <incremented_number>
which avoid to iterate over all the commits in case that there is more than 100 commits referencing your file
Here is an implementation in javascript using graphql.js :
const graphql = require('graphql.js');
const token = "YOUR_TOKEN";
const queryVars = { name: "linux", owner: "torvalds" };
const file = "Makefile";
const branch = "master";
var graph = graphql("https://api.github.com/graphql", {
headers: {
"Authorization": `Bearer ${token}`,
'User-Agent': 'My Application'
},
asJSON: true
});
graph(`
query ($name: String!, $owner: String!){
repository(owner: $owner, name: $name) {
content: object(expression: "${branch}:${file}") {
... on Blob {
text
}
}
info: ref(qualifiedName: "${branch}") {
target {
... on Commit {
history(first: 1, path: "${file}") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
pageInfo {
endCursor
}
totalCount
}
}
}
}
}
}
`)(queryVars).then(function(response) {
console.log(JSON.stringify(response, null, 2));
var totalCount = response.repository.info.target.history.totalCount;
if (totalCount > 1) {
var cursorPrefix = response.repository.info.target.history.pageInfo.endCursor.split(" ")[0];
var nextCursor = `${cursorPrefix} ${totalCount-2}`;
console.log(`total count : ${totalCount}`);
console.log(`cursorPrefix : ${cursorPrefix}`);
console.log(`get element after cursor : ${nextCursor}`);
graph(`
query ($name: String!, $owner: String!){
repository(owner: $owner, name: $name) {
info: ref(qualifiedName: "${branch}") {
target {
... on Commit {
history(first: 1, after:"${nextCursor}", path: "${file}") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
}
}
}
}
}
}`)(queryVars).then(function(response) {
console.log("first commit info");
console.log(JSON.stringify(response, null, 2));
}).catch(function(error) {
console.log(error);
});
}
}).catch(function(error) {
console.log(error);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With