Informationen zu Octokit.js
Wenn du ein Skript mit JavaScript schreiben möchtest, um mit der REST-API von GitHub zu interagieren, empfiehlt GitHub die Verwendung des Octokit.js-SDK. Octokit.js wird von GitHub verwaltet. Vom SDK werden bewährte Methoden implementiert, und es erleichtert dir, über JavaScript mit der REST-API zu interagieren. Octokit.js funktioniert mit allen modernen Browsern, Node.js und Deno. Weitere Informationen zu Octokit.js findest du in der Octokit.js-Infodatei.
Voraussetzungen
In diesem Leitfaden wird davon ausgegangen, dass du mit JavaScript und der GitHub-REST-API vertraut bist. Weitere Informationen zur REST-API findest du unter Erste Schritte mit der REST-API.
Du musst octokit
installieren und importieren, um die Octokit.js-Bibliothek nutzen zu können. In diesem Leitfaden werden Importanweisungen gemäß ES6 verwendet. Weitere Informationen zu verschiedenen Installations- und Importmethoden findest du im Abschnitt „Verwendung“ der Octokit.js-Infodatei.
Instanziieren und Authentifizieren
Warnung: Verwende die Anmeldeinformationen für die Authentifizierung wie ein Kennwort.
Zum Schutz deiner Anmeldeinformationen kannst du sie als Geheimnis speichern und dein Skript über GitHub Actions ausführen. Weitere Informationen findest du unter Verwenden von Geheimnissen in GitHub-Aktionen.
Wenn dies nicht möglich ist, solltest du einen anderen CLI-Dienst verwenden, um die Anmeldeinformationen sicher zu speichern.
Authentifizieren mit einem personal access token
Wenn du die GitHub-REST-API für den privaten Gebrauch nutzen möchtest, kannst du ein personal access token erstellen. Weitere Informationen zum Erstellen eines personal access token findest du unter Verwalten deiner persönlichen Zugriffstoken.
Importiere zunächst Octokit
aus octokit
. Übergib dann dein personal access token, wenn du eine Instanz von Octokit
erstellst. Ersetze im folgenden Beispiel YOUR-TOKEN
durch einen Verweis auf dein personal access token. Ersetze HOSTNAME
durch den Namen von Ihre GitHub Enterprise Server-Instance.
import { Octokit } from "octokit"; const octokit = new Octokit({ baseUrl: "http(s)://HOSTNAME/api/v3", auth: 'YOUR-TOKEN', });
import { Octokit } from "octokit";
const octokit = new Octokit({
baseUrl: "http(s)://HOSTNAME/api/v3",
auth: 'YOUR-TOKEN',
});
Authentifizieren mit einer GitHub App
Wenn du die API im Namen einer Organisation oder eines anderen Benutzers nutzen möchtest, empfiehlt GitHub, dass du eine GitHub App verwendest. Wenn ein Endpunkt für GitHub Apps verfügbar ist, ist in der REST-Referenzdokumentation für diesen Endpunkt angegeben, welche Art von GitHub App-Token erforderlich ist. Weitere Informationen finden Sie unter Registrieren einer GitHub-App und unter Informationen zur Authentifizierung mit einer GitHub-App.
Statt Octokit
aus octokit
zu importieren, importiere App
. Ersetze APP_ID
im folgenden Beispiel durch einen Verweis auf die ID deiner App. Ersetze PRIVATE_KEY
durch einen Verweis auf den privaten Schlüssel deiner App. Ersetze INSTALLATION_ID
durch die ID der Installation der App, für die du dich authentifizieren möchtest. Auf der Einstellungsseite für die App findest du die ID der App und kannst einen privaten Schlüssel generieren. Weitere Informationen findest du unter Verwalten privater Schlüssel für GitHub-Apps. Eine Installations-ID kannst du mit den Endpunkten GET /users/{username}/installation
, GET /repos/{owner}/{repo}/installation
oder GET /orgs/{org}/installation
abrufen. Weitere Informationen finden Sie unter „REST-API-Endpunkte für GitHub Apps.“ Ersetzen Sie HOSTNAME
durch den Namen von Ihre GitHub Enterprise Server-Instance.
import { App } from "octokit"; const app = new App({ appId: APP_ID, privateKey: PRIVATE_KEY, Octokit: Octokit.defaults({ baseUrl: "http(s)://HOSTNAME/api/v3", }), }); const octokit = await app.getInstallationOctokit(INSTALLATION_ID);
import { App } from "octokit";
const app = new App({
appId: APP_ID,
privateKey: PRIVATE_KEY,
Octokit: Octokit.defaults({
baseUrl: "http(s)://HOSTNAME/api/v3",
}),
});
const octokit = await app.getInstallationOctokit(INSTALLATION_ID);
Authentifizieren in GitHub Actions
Wenn du die API in einem GitHub Actions-Workflow verwenden möchtest, empfiehlt GitHub, dass du dich mit dem integrierten GITHUB_TOKEN
authentifizierst, anstatt ein Token zu erstellen. Du kannst den GITHUB_TOKEN
mit dem Schlüssel permissions
Berechtigungen erteilen. Weitere Informationen zu GITHUB_TOKEN
findest du unter Automatische Tokenauthentifizierung.
Wenn in deinem Workflow auf Ressourcen außerhalb des Repositorys des Workflows zugegriffen werden muss, kannst du GITHUB_TOKEN
nicht verwenden. Speichere die Anmeldeinformationen in diesem Fall als Geheimnis und ersetze GITHUB_TOKEN
in den folgenden Beispielen durch den Namen des Geheimnisses. Weitere Informationen zu Geheimnissen findest du unter Verwenden von Geheimnissen in GitHub-Aktionen.
Wenn du das Schlüsselwort run
verwendest, um dein JavaScript-Skript in deinen GitHub Actions-Workflows auszuführen, kannst du den Wert von GITHUB_TOKEN
als Umgebungsvariable speichern. Vom Skript kann als process.env.VARIABLE_NAME
auf die Umgebungsvariable zugegriffen werden.
Beispiel: In diesem Workflowschritt wird GITHUB_TOKEN
in einer Umgebungsvariable mit der Bezeichnung TOKEN
gespeichert:
- name: Run script
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
node .github/actions-scripts/use-the-api.mjs
Vom Skript, das vom Workflow ausgeführt wird, wird process.env.TOKEN
zur Authentifizierung verwendet:
import { Octokit } from "octokit"; const octokit = new Octokit({ baseUrl: "http(s)://HOSTNAME/api/v3", auth: process.env.TOKEN, });
import { Octokit } from "octokit";
const octokit = new Octokit({
baseUrl: "http(s)://HOSTNAME/api/v3",
auth: process.env.TOKEN,
});
Instanziieren ohne Authentifizierung
Du kannst die REST-API ohne Authentifizierung verwenden, obwohl du dann eine niedrigere Ratenbegrenzung hast und einige Endpunkte nicht verwenden kannst. Wenn du eine Instanz von Octokit
ohne Authentifizierung erstellen möchtest, übergibst du das Argument auth
nicht. Lege die Basis-URL auf http(s)://HOSTNAME/api/v3
fest. Ersetze [hostname]
durch den Namen von Ihre GitHub Enterprise Server-Instance.
import { Octokit } from "octokit"; const octokit = new Octokit({ baseUrl: "http(s)://HOSTNAME/api/v3", });
import { Octokit } from "octokit";
const octokit = new Octokit({
baseUrl: "http(s)://HOSTNAME/api/v3",
});
Ausführen von Anforderungen
Octokit unterstützt mehrere Möglichkeiten, Anforderungen auszuführen. Du kannst die request
-Methode verwenden, um Anforderungen auszuführen, wenn du HTTP-Verb und -Pfad für den Endpunkt kennst. Du kannst die rest
-Methode verwenden, wenn du die Vorteile der automatischen Vervollständigung in der IDE und bei der Eingabe nutzen möchtest. Für paginierte Endpunkte kannst du die paginate
-Methode verwenden, um mehrere Datenseiten anzufordern.
Verwenden der request
-Methode zum Ausführen von Anforderungen
Übergebe zum Ausführen von Anforderungen mit der request
-Methode HTTP-Methode und -Pfad als erstes Argument. Gib alle Text-, Abfrage- oder Pfadparameter als zweites Argument in einem Objekt an. Beispiel: Zum Ausführen einer GET
-Anforderung an /repos/{owner}/{repo}/issues
und Übergeben der Parameter owner
, repo
und per_page
:
await octokit.request("GET /repos/{owner}/{repo}/issues", { owner: "github", repo: "docs", per_page: 2 });
await octokit.request("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 2
});
Bei der request
-Methode wird der Header Accept: application/vnd.github+json
automatisch übergeben. Füge zum Übergeben zusätzlicher Header oder eines anderen Accept
-Headers dem Objekt eine headers
-Eigenschaft hinzu, die als zweites Argument übergeben wird. Der Wert der Eigenschaft headers
ist ein Objekt mit den Headernamen als Schlüssel und den Headerwerten als Werte. Beispiel: Senden eines content-type
-Headers mit dem Wert text/plain
:
await octokit.request("POST /markdown/raw", { text: "Hello **world**", headers: { "content-type": "text/plain", }, });
await octokit.request("POST /markdown/raw", {
text: "Hello **world**",
headers: {
"content-type": "text/plain",
},
});
Verwenden von rest
-Endpunktmethoden zum Ausführen von Anforderungen
Jeder REST-API-Endpunkt verfügt über eine zugeordnete rest
-Endpunktmethode in Octokit. Diese Methoden werden in der Regel in der IDE automatisch vervollständigt. Du kannst beliebige Parameter als Objekt an die Methode übergeben.
await octokit.rest.issues.listForRepo({ owner: "github", repo: "docs", per_page: 2 });
await octokit.rest.issues.listForRepo({
owner: "github",
repo: "docs",
per_page: 2
});
Wenn du eine typisierte Sprache wie TypeScript verwendest, kannst du außerdem Typen für die Verwendung mit diesen Methoden importieren. Weitere Informationen findest du im Abschnitt „TypeScript“ der plugin-rest-endpoint-methods.js-Infodatei.
Ausführen paginierter Anforderungen
Wenn der Endpunkt paginiert ist und du mehr als eine Seite mit Ergebnissen abrufen möchtest, kannst du die paginate
-Methode verwenden. paginate
ruft die nächste Ergebnisseite ab, bis die letzte Seite erreicht ist, und gibt dann alle Ergebnisse als einzelnes Array zurück. Einige Endpunkte geben paginierte Ergebnisse als Array in einem Objekt zurück, anstatt die paginierten Ergebnisse als Array zurückzugeben. paginate
gibt immer ein Array aus Elementen zurück, auch wenn das Rohergebnis ein Objekt war.
So werden im folgenden Beispiel alle Issues aus dem Repository github/docs
abgerufen. Obwohl 100 Issues gleichzeitig angefordert werden, wird die Funktion erst zurückgegeben, wenn die letzte Datenseite erreicht ist.
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", { owner: "github", repo: "docs", per_page: 100, });
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
});
Die paginate
-Methode akzeptiert eine optionale Zuordnungsfunktion, die du verwenden kannst, um ausschließlich die Daten zu sammeln, die du aus der Antwort erhalten möchtest. Dadurch wird die Arbeitsspeicherauslastung des Skripts reduziert. In der Zuordnungsfunktion kann ein zweites Argument (done
) verwendet werden, das du aufrufen kannst, um die Paginierung zu beenden, bevor die letzte Seite erreicht ist. Dadurch kannst du eine Teilmenge der Seiten abrufen. Im folgenden Beispiel werden beispielsweise weiterhin Ergebnisse abgerufen, bis ein Issue zurückgegeben wird, das im Titel „test“ enthält. Für die zurückgegebenen Datenseiten werden nur der Titel und der Autor des Issue gespeichert.
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", { owner: "github", repo: "docs", per_page: 100, }, (response, done) => response.data.map((issue) => { if (issue.title.includes("test")) { done() } return ({title: issue.title, author: issue.user.login}) }) );
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
},
(response, done) => response.data.map((issue) => {
if (issue.title.includes("test")) {
done()
}
return ({title: issue.title, author: issue.user.login})
})
);
Anstatt alle Ergebnisse gleichzeitig abzurufen, kannst du octokit.paginate.iterator()
verwenden, um jeweils eine einzelne Seite zu durchlaufen. So wird im folgenden Beispiel jeweils eine Seite mit Ergebnissen abgerufen und es wird jedes Objekt von der Seite verarbeitet, bevor die nächste Seite abgerufen wird. Sobald ein Issue erreicht ist, das im Titel „Test“ enthält, beendet das Skript die Iteration und gibt Titel und Autor des Issues für jedes verarbeitete Objekt zurück. Der Iterator ist die speichereffizienteste Methode zum Abrufen paginierter Daten.
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/issues", { owner: "github", repo: "docs", per_page: 100, }); let issueData = [] let breakLoop = false for await (const {data} of iterator) { if (breakLoop) break for (const issue of data) { if (issue.title.includes("test")) { breakLoop = true break } else { issueData = [...issueData, {title: issue.title, author: issue.user.login}]; } } }
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
});
let issueData = []
let breakLoop = false
for await (const {data} of iterator) {
if (breakLoop) break
for (const issue of data) {
if (issue.title.includes("test")) {
breakLoop = true
break
} else {
issueData = [...issueData, {title: issue.title, author: issue.user.login}];
}
}
}
Du kannst die paginate
-Methode auch mit den rest
-Endpunktmethoden verwenden. Übergib die rest
-Endpunktmethode als erstes Argument. Übergib alle Parameter als zweites Argument.
const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, { owner: "github", repo: "docs", per_page: 100, });
const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {
owner: "github",
repo: "docs",
per_page: 100,
});
Weitere Informationen zur Paginierung findest du unter Verwenden der Paginierung in der REST-API.
Abfangen von Fehlern
Abfangen aller Fehler
Manchmal wird von der GitHub-REST-API ein Fehler zurückgegeben. Beispielsweise erhältst du eine Fehlermeldung, wenn das Zugriffstoken abgelaufen ist oder wenn du einen erforderlichen Parameter ausgelassen hast. Von Octokit.js wird die Anforderung automatisch wiederholt, wenn ein anderer Fehler als 400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
und 422 Unprocessable Entity
angezeigt wird. Wenn sogar nach wiederholten Versuchen ein API-Fehler auftritt, wird von Octokit.js eine Fehlermeldung ausgegeben, die den HTTP-Statuscode der Antwort (response.status
) und die Antwortheader (response.headers
) enthält. Du musst diese Fehler im Code behandeln. Du kannst beispielsweise einen try/catch-Block verwenden, um Fehler abzufangen:
let filesChanged = [] try { const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", { owner: "github", repo: "docs", pull_number: 22809, per_page: 100, }); for await (const {data} of iterator) { filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)]; } } catch (error) { if (error.response) { console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`) } console.error(error) }
let filesChanged = []
try {
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", {
owner: "github",
repo: "docs",
pull_number: 22809,
per_page: 100,
});
for await (const {data} of iterator) {
filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];
}
} catch (error) {
if (error.response) {
console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
}
console.error(error)
}
Behandeln beabsichtigter Fehlercodes
Manchmal wird von GitHub ein 4xx-Statuscode dazu verwendet, eine Nicht-Fehlerantwort anzugeben. Wenn der von dir verwendete Endpunkt dies tut, kannst du zusätzliche Behandlung für bestimmte Fehler hinzufügen. Beispielsweise wird vom Endpunkt GET /user/starred/{owner}/{repo}
der Statuscode 404
zurückgegeben, wenn das Repository nicht mit einem Stern versehen ist. Im folgenden Beispiel wird die Antwort 404
verwendet, um anzugeben, dass das Repository nicht mit einem Stern versehen wurde. Alle anderen Fehlercodes werden als Fehler behandelt.
try { await octokit.request("GET /user/starred/{owner}/{repo}", { owner: "github", repo: "docs", }); console.log(`The repository is starred by me`); } catch (error) { if (error.status === 404) { console.log(`The repository is not starred by me`); } else { console.error(`An error occurred while checking if the repository is starred: ${error?.response?.data?.message}`); } }
try {
await octokit.request("GET /user/starred/{owner}/{repo}", {
owner: "github",
repo: "docs",
});
console.log(`The repository is starred by me`);
} catch (error) {
if (error.status === 404) {
console.log(`The repository is not starred by me`);
} else {
console.error(`An error occurred while checking if the repository is starred: ${error?.response?.data?.message}`);
}
}
Behandeln von Ratenlimitfehlern
Wenn ein Ratenlimitfehler angezeigt wird, solltest du die Anforderung nach einer Wartezeit wiederholen. Wenn die Rate begrenzt ist, antwortet GitHub mit dem Fehler 403 Forbidden
, und der Wert des Antwortheaders x-ratelimit-remaining
lautet "0"
. Die Antwortheader enthalten einen x-ratelimit-reset
-Header, in dem der Zeitpunkt (in UTC-Epochensekunden) angegeben ist, zu dem das aktuelle Ratenlimitfenster zurückgesetzt wird. Du kannst die Anforderung nach der Zeit wiederholen, die im Header x-ratelimit-reset
angegeben ist.
async function requestRetry(route, parameters) { try { const response = await octokit.request(route, parameters); return response } catch (error) { if (error.response && error.status === 403 && error.response.headers['x-ratelimit-remaining'] === '0') { const resetTimeEpochSeconds = error.response.headers['x-ratelimit-reset']; const currentTimeEpochSeconds = Math.floor(Date.now() / 1000); const secondsToWait = resetTimeEpochSeconds - currentTimeEpochSeconds; console.log(`You have exceeded your rate limit. Retrying in ${secondsToWait} seconds.`); setTimeout(requestRetry, secondsToWait * 1000, route, parameters); } else { console.error(error); } } } const response = await requestRetry("GET /repos/{owner}/{repo}/issues", { owner: "github", repo: "docs", per_page: 2 })
async function requestRetry(route, parameters) {
try {
const response = await octokit.request(route, parameters);
return response
} catch (error) {
if (error.response && error.status === 403 && error.response.headers['x-ratelimit-remaining'] === '0') {
const resetTimeEpochSeconds = error.response.headers['x-ratelimit-reset'];
const currentTimeEpochSeconds = Math.floor(Date.now() / 1000);
const secondsToWait = resetTimeEpochSeconds - currentTimeEpochSeconds;
console.log(`You have exceeded your rate limit. Retrying in ${secondsToWait} seconds.`);
setTimeout(requestRetry, secondsToWait * 1000, route, parameters);
} else {
console.error(error);
}
}
}
const response = await requestRetry("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 2
})
Verwenden der Antwort
Bei der Methode request
wird eine Zusage zurückgegeben, die in ein Objekt aufgelöst wird, wenn die Anforderung erfolgreich war. Die Objekteigenschaften sind data
(der vom Endpunkt zurückgegebene Antworttext), status
(der HTTP-Antwortcode), url
(die URL der Anforderung) und headers
(ein Objekt, das die Antwortheader enthält). Sofern nicht anders angegeben, verwendet der Antworttext das JSON-Format. Von einigen Endpunkten wird kein Antworttext zurückgegeben. In diesen Fällen wird die Eigenschaft data
weggelassen.
const response = await octokit.request("GET /repos/{owner}/{repo}/issues/{issue_number}", { owner: "github", repo: "docs", issue_number: 11901, }); console.log(`The status of the response is: ${response.status}`) console.log(`The request URL was: ${response.url}`) console.log(`The x-ratelimit-remaining response header is: ${response.headers["x-ratelimit-remaining"]}`) console.log(`The issue title is: ${response.data.title}`)
const response = await octokit.request("GET /repos/{owner}/{repo}/issues/{issue_number}", {
owner: "github",
repo: "docs",
issue_number: 11901,
});
console.log(`The status of the response is: ${response.status}`)
console.log(`The request URL was: ${response.url}`)
console.log(`The x-ratelimit-remaining response header is: ${response.headers["x-ratelimit-remaining"]}`)
console.log(`The issue title is: ${response.data.title}`)
Auf ähnliche Weise wird bei der Methode paginate
eine Zusage zurückgegeben. Wenn die Anforderung erfolgreich war, wird die Zusage in ein Array von Daten aufgelöst, die vom Endpunkt zurückgegeben werden. Anders als bei der Methode request
werden bei der Methode paginate
Statuscode, URL oder Header nicht zurückgegeben.
const data = await octokit.paginate("GET /repos/{owner}/{repo}/issues", { owner: "github", repo: "docs", per_page: 100, }); console.log(`${data.length} issues were returned`) console.log(`The title of the first issue is: ${data[0].title}`)
const data = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
});
console.log(`${data.length} issues were returned`)
console.log(`The title of the first issue is: ${data[0].title}`)
Beispielskript
Hier siehst du ein vollständiges Beispielskript, in dem Octokit.js verwendet wird. Durch das Skript wird Octokit
importiert, und es wird eine neue Instanz von Octokit
erstellt. Wenn du dich mit einer GitHub App statt durch ein personal access token authentifizieren möchtest, würdest du App
anstelle von Octokit
importieren und instanziieren. Weitere Informationen findest du unter Authentifizieren mit einer GitHub App.
Durch die Funktion getChangedFiles
werden alle Dateien abgerufen, die für einen Pull Request geändert wurden. Durch die Funktion commentIfDataFilesChanged
wird die Funktion getChangedFiles
aufgerufen. Wenn eine der Dateien, die vom Pull Request geändert wurden, /data/
im Dateipfad enthält, wird der Pull Request von der Funktion kommentiert.
import { Octokit } from "octokit"; const octokit = new Octokit({ baseUrl: "http(s)://HOSTNAME/api/v3", auth: 'YOUR-TOKEN', }); async function getChangedFiles({owner, repo, pullNumber}) { let filesChanged = [] try { const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", { owner: owner, repo: repo, pull_number: pullNumber, per_page: 100, }); for await (const {data} of iterator) { filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)]; } } catch (error) { if (error.response) { console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`) } console.error(error) } return filesChanged } async function commentIfDataFilesChanged({owner, repo, pullNumber}) { const changedFiles = await getChangedFiles({owner, repo, pullNumber}); const filePathRegex = new RegExp(/\/data\//, "i"); if (!changedFiles.some(fileName => filePathRegex.test(fileName))) { return; } try { const {data: comment} = await octokit.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", { owner: owner, repo: repo, issue_number: pullNumber, body: `It looks like you changed a data file. These files are auto-generated. \n\nYou must revert any changes to data files before your pull request will be reviewed.`, }); return comment.html_url; } catch (error) { if (error.response) { console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`) } console.error(error) } } await commentIfDataFilesChanged({owner: "github", repo: "docs", pullNumber: 191});
import { Octokit } from "octokit";
const octokit = new Octokit({
baseUrl: "http(s)://HOSTNAME/api/v3",
auth: 'YOUR-TOKEN',
});
async function getChangedFiles({owner, repo, pullNumber}) {
let filesChanged = []
try {
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", {
owner: owner,
repo: repo,
pull_number: pullNumber,
per_page: 100,
});
for await (const {data} of iterator) {
filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];
}
} catch (error) {
if (error.response) {
console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
}
console.error(error)
}
return filesChanged
}
async function commentIfDataFilesChanged({owner, repo, pullNumber}) {
const changedFiles = await getChangedFiles({owner, repo, pullNumber});
const filePathRegex = new RegExp(/\/data\//, "i");
if (!changedFiles.some(fileName => filePathRegex.test(fileName))) {
return;
}
try {
const {data: comment} = await octokit.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", {
owner: owner,
repo: repo,
issue_number: pullNumber,
body: `It looks like you changed a data file. These files are auto-generated. \n\nYou must revert any changes to data files before your pull request will be reviewed.`,
});
return comment.html_url;
} catch (error) {
if (error.response) {
console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
}
console.error(error)
}
}
await commentIfDataFilesChanged({owner: "github", repo: "docs", pullNumber: 191});
Nächste Schritte
- Weitere Informationen zu Octokit.js findest du in der Dokumentation zu Octokit.js.
- Einige Beispiele aus der Praxis kannst du nachvollziehen, indem du dir ansiehst, wie Octokit.js von GitHub Docs verwendet wird. Durchsuche zu diesem Zweck das GitHub Docs-Repository.