Giter Club home page Giter Club logo

octokit-next.js's Introduction

octokit-next.js

Experimental Octokit SDK for exploration only - DO NOT USE ๐Ÿšซโš ๏ธ

Build Status

We use this repository to implement new features without the legacy of the current Octokit implementation.

This project is built as a monorepo using npm workspaces and is publishing native ES Modules. To set it up and run the tests Node 18 is required.

Currently working on:

Usage

โš ๏ธ This is an experimental SDK not meant for actual usage.

import { Octokit } from "octokit-next";

const octokit = new Octokit();

const { data } = await octokit.request("GET /repos/{owner}/{repo}", {
  owner: "octokit",
  repo: "octokit-next.js",
});

console.log(data);

Breaking changes

A list of breaking changes compared to latest @octokit/* modules

  • Node 16 and other JavaScript runtime environments that lack a global fetch() method are no longer supported out-of-the-box. A fetch method such as provided by the node-fetch npm module can be passed to make Octokit work in these environments.

    For @octokit-next/core and other SDKs built upon it you can do this

    import { Octokit } from "octokit-next";
    import fetch from "node-fetch";
    
    const octokit = new Octokit({ request: { fetch } });

    For the static @octokit-next/request method you can do this

    import { request } from "@octokit-next/request";
    import fetch from "node-fetch";
    
    const result = await request("GET /", { request: { fetch } });
  • Octokit.defaults is now Octokit.withDefaults

  • Octokit.plugin is now Octokit.withPlugins. Instead of accepting one argument per plugin, the method now accepts a single array argument with all plugins to be applied.

  • @octokit/openapi-types will be renamed to @octokit/types-openapi to be consistents with the @octokit/types-* prefixed packages that only contain types

  • @octokit/auth-token: createTokenAuth() no longer accepts a token string argument, but requires options.token.

  • plugins now receive all options passed to the Octokit constructor as well as its defaults. Previously only the options passed to the constructor were passed

Features

  • Octokit.DEFAULTS
  • octokit.options

Notes for later

  • replace request.defaults() and endpoint.defaults() with request.withDefaults() and endpoint.withDefaults()
  • remove options.previews from new Octokit(options)
  • Add script to verify that packages/* folders and release.plugins configuration in package.json are in sync
  • scripts/types-rest-api-diff/update.js - remove all package folders before re-creating, so that obsolete packages get removed

Known issues

  • Constructor option Types (options.auth) are not set correctly when authStrategy is set via .withDefaults({ authStrategy }) (#20)
  • Endpoint types don't work if they changed between versions (#28)

License

MIT

octokit-next.js's People

Contributors

aarondewes avatar g-rath avatar gr2m avatar haroenv avatar joshuakgoldberg avatar kfcampbell avatar nickfloyd avatar octokitbot avatar oscard0m avatar renovate[bot] avatar wolfy1339 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

octokit-next.js's Issues

Dependency Dashboard

This issue provides visibility into Renovate updates and their statuses. Learn more

This repository currently has no open or pending branches.


  • Check this box to trigger a request for Renovate to run again on this repository

Make the `authStrategy` parameter work with the static `.withDefaults()` method

follow up to #18 and related to #11

What we want is the following

import { Octokit } from "@octokit-next/core";

type CallbackStrategyOptions = {
  callback: () => string | Promise<string>;
};

function createCallbackAuth(options: CallbackStrategyOptions) {
  return async function auth() {
    return options.callback();
  };
}

const OctokitWithCallbackAuth = Octokit.withDefaults({
  authStrategy: createCallbackAuth,
});

// compiler should complain: `{ auth }` should be required because `authStrategy` is set to `createCallbackAuth` by default
new OctokitWithCallbackAuth();

Here is how auth strategies work in Octokit via the authStrategy and auth options:
https://github.com/octokit/authentication-strategies.js#authenticationstrategystrategyoptions

implement the full functionality of `@octokit/request` in `@octokit-next/request`

Including all of the README, tests, and whatever else is implemented in @octokit/request. Compare to https://github.com/octokit/octokit-next.js/tree/main/packages/endpoint

  • Move tests from https://github.com/octokit/request.js/ into /packages/request/test. Rewrite the tests from TS/Jest to JS/uvu
  • Add test, test:code, test:types scripts to the package.json
  • Add type tests to index.test-d.ts
  • Make sure RequestInterface includes the .endpoint APIs

TypeScript performance

I'm happy with the TypeScript IntelliSense we can provide for different REST API versions in the upcoming Octokit, however the current implementations seems to overwhelm the TypeScript engine. It gets very slow at times, you can see it in the videos I posted at octokit/octokit.js#2127 (comment)

I can understand that TypeScript gets slow, we do work with hundreds of REST API endpoints which are referenced and combined with new definitions for versions other than github.com. But I hope that we can find a way to optimize the speed of the TypeScript lookups to make it usable.

I could really use help with this, as I have no idea how to profile TypeScript when working with VS Code.

To see what I mean, try the following:

  1. In a new folder, run npm init -y && npm install @octokit-next/core
  2. Create an index.ts file with the following content
// import "@octokit-next/types-rest-api";

import { Octokit } from "@octokit-next/core";

export async function test() {
  const octokit = new Octokit({
    auth: "token 0000000000000000000000000000000000000001",
  });

  const responseRepo = await octokit.request("GET /repos/{owner}/{repo}", {
    owner: "octokit-fixture-org",
    repo: "hello-world",
  });
  expectType<string>(responseRepo.data.owner.login);
}

function expectType<T>(value: T): void {}

Now the import in first line and see how long it takes for TypeScript to catch up with the new types for the GET /repos/{owner}/{repo} endpoint.

There are other examples that can be seen in the video, but figuring out how we could improve the performance for this particular case would be a great start.

Github Action Failure

Hey not sure if I am opening an issue to the right place:

We use: https://github.com/actions/first-interaction and today suddenly it stopped working with an issue:

Run actions/first-interaction@v1
  with:
    repo-token: ***
    pr-message: Hey @FallingCeilingS ๐Ÿ‘‹.
  Thank you for contributing to Neo4j Design Language, or Needle ๐Ÿชก in short.
  
  Be sure to follow the [contribution](https://github.com/neo4j/neo4j-design/blob/main/CONTRIBUTING.md) guidelines ๐Ÿ™Œ
  
  
/usr/bin/docker run --name f70630e68b[2](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:2)45c7475994[3](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:3)c00[4](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:4)ab4af8e91_c66cb4 --label 817f70 --workdir /github/workspace --rm -e "INPUT_REPO-TOKEN" -e "INPUT_PR-MESSAGE" -e "INPUT_ISSUE-MESSAGE" -e "HOME" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/neo4j-design/neo4j-design":"/github/workspace" 817f70:630e68b24[5](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:5)c74759943c004ab4af8e91
internal/modules/cjs/loader.js:121[6](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:6)
      throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
      ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /node_modules/@octokit/graphql/index.js
require() of ES modules is not supported.
require() of /node_modules/@octokit/graphql/index.js from /node_modules/@actions/github/lib/github.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /node_modules/@octokit/graphql/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1216:13)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:93[7](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:7):14)
    at Module.require (internal/modules/cjs/loader.js:10[8](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:8)[9](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:9):1[9](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:10))
    at require (internal/modules/cjs/helpers.js:73:18)
    at Object.<anonymous> (/node_modules/@actions/github/lib/github.js:14:19)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:[10](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:11))
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:[14](https://github.com/neo4j/neo4j-design/actions/runs/3150161627/jobs/5122781583#step:3:15)) {
  code: 'ERR_REQUIRE_ESM'
}

And I suspect that it may have something to do with this repo, as you are publishing to 2.3.0 and the latest is this instead the 5.x.x: https://cdn.jsdelivr.net/npm/@octokit/graphql@latest/package.json

Create types for a set of endpoints for "github.com", "ghes-3.1", "ghes-3.0"

  • 1 endpoint that exists on all versions
  • 1 endpoint that exist on github.com, but not on ghes-*
  • 1 endpoint that exist on github.com and ghes-3.1, but not on ghes-3.0
  • 1 endpoint that exist on ghes-3.1, but not on ghes-3.0 and github.com
  • 1 endpoint that exists on all versions, but has additional parameters and response keys on github.com
  • Define a response header that only exists on github.com and is not set if version is set to a ghes-* version
  • Define a response header that only exists on ghes-* and is not set if version is set to github.com
  • Add tests for both JS/DTS and TS
  • Add the GET / root endpoint by default, move all other endpoints to a separate package and make it optional
  • Setup up repository as mono-repo using npm workspaces

Make `Octokit.ApiVersions` interface merging work with GHES additions in TypeScript

This is a follow up to #7

Here is a video summarizing the problem. The file I'm showing is tests/ts/ghes-3.1/test.ts

2021-08-09.12-51-01.mp4

I also created a TypeScript playground with a very much simplified illustration of the problem I'm running into.

The @octokit-next/* packages are published from the packages/ folders. They are written in JavaScript and hand-written d.ts files.

When installing @octokit-next/core, then the version constructor parameter can only be set to "github.com" and the only declared REST API endpoint is the root endpoint GET /.


image


When installing @octokit-next/types-rest-api-github.com and importing it, then the additional endpoints show up


image


However, when installing and importing @octokit-next/types-rest-api-ghes-3.1, then the version constructor option cannot be set to "ghes-3.1", although it is added as key to the Octokit.ApiVersions interface:


image


declare module "@octokit-next/types" {
namespace Octokit {
interface ApiVersions {
"ghes-3.1": {
ResponseHeaders: GHES31ResponseHeaders;
Endpoints: Octokit.ApiVersions["github.com"]["Endpoints"] &
GHES30EndpointsDiff;
};
}
}
}


I added tests for both JavaScript (using tsd) and TypeScript (using tsc) examples in tests/js and tests/ts respectively.

The JS/DTS tests are passing, but the TypeScript test for GHES-3.1 is failing. And I'm not sure why that is turns out the the JS/DTS tests used a custom class where I explicitly set the versions. I now added a new tests/js/ghes-3.1 test that fails just like its TypeScript counterpart

Deno compatibility

I spent some time on testing with Deno.

Things look good, I even added a smoke test:
#83

However loading the type-only modules (@octokit-next/types*) is not working as expected.

First, there is a problem with https://esm.sh that I described at esm-dev/esm.sh#433. I found a workaround.
But then I ran into a problem with Deno itself: it doesn't seem to parse the types of Type-only packages, unless I'm missing something: denoland/deno#16239

It does work in the TypeScript playground and with node code edited in VS code. But Deno doesn't seem to be able to handle it at this point ๐Ÿคท๐Ÿผ

Add the authentication strategy options (`authStrategy`, `auth`) and make the types for `auth` depend on what `authStrategy` is set to, either as part of the same options object or via `.defaults()`

I made the show on the topic: gr2m/helpdesk#29

An approach that eventually worked: TypeScript playground

The goal here is

  1. If authStrategy is not set, require auth to be set to a string (token)

  2. If authStrategy is set, make sure it adheres to a common interface:

    • a synchronous "strategy" function, which returns an asynchrnous "auth" function
    • the returned "auth" function has a .hook property that can be used to hook into the request lifecycle
    • How authentication strategies work

    and derive the types for auth from the strategy function options

  3. Make it work for custom classes created with .withDefaults(), e.g.

    const AppOctokit = Octokit.defaults({ authStrategy: createAppAuth })
    const appOctokit = new AppOctokit()
    // ^ complains that `auth` must be set to `{ appId: string, privateKey: string, ... etc  }`

Breaking changes backlog

Keeping track of changes that will require deprecations / breaking changes for the migration from current @octokt/* packages to the respective @octokit-next/* packages

  • @octokit/openapi-types will be renamed to @octokit/types-openapi to be consistents with the @octokit/types-* prefixed packages that only contain types

replace `uvu` with `ava`

At the time when I wrote the library, only the uvu npm package was available as test runner with good ESM compatibility. With version 4 we can also use ava, which is much more established, plus it has snapshot testing which will be very useful for github-project

Instead of using the uvu/assert module for assertions, we will have to use ava's assertions, as documented here:
https://github.com/avajs/ava/blob/main/docs/03-assertions.md

See gr2m/github-project#29 as reference to the same migration

Remove `node-fetch` by default

Node 18 comes with a global fetch built-in. Node 14 will be out of maintenance end of April 2023, and Node 16 on a few months later on Sep 11. Node 18 is already the current stable release today.

Using node-fetch is a continuous pain point. Using ESM and conditional exports might help, but I think we should do a clean cut instead.

Adding node-fetch is fairly simple anyway.

Instead of

import { Octokit } from "octokit"
const octokit = new Octokit()

Developers will need to do

import { Octokit } from "octokit"
import fetch from "node-fetch"
const octokit = new Octokit({ request: { fetch } })

We can also throw a helpful error in case a global fetch is not defined, specific to the runtime environment.

The automated release is failing ๐Ÿšจ

๐Ÿšจ The automated release from the main branch failed. ๐Ÿšจ

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. Iโ€™m sure you can fix this ๐Ÿ’ช.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those donโ€™t help, or if this issue is reporting something you think isnโ€™t right, you can always ask the humans behind semantic-release.


Missing package.json file.

A package.json file at the root of your project is required to release on npm.

Please follow the npm guideline to create a valid package.json file.


Missing package.json file.

A package.json file at the root of your project is required to release on npm.

Please follow the npm guideline to create a valid package.json file.


Missing package.json file.

A package.json file at the root of your project is required to release on npm.

Please follow the npm guideline to create a valid package.json file.


Missing package.json file.

A package.json file at the root of your project is required to release on npm.

Please follow the npm guideline to create a valid package.json file.


Good luck with your project โœจ

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

The automated release is failing ๐Ÿšจ

๐Ÿšจ The automated release from the main branch failed. ๐Ÿšจ

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. Iโ€™m sure you can fix this ๐Ÿ’ช.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those donโ€™t help, or if this issue is reporting something you think isnโ€™t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project โœจ

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

Generate types for all endpoints of `github.com`, `ghes-3.1`, and `ghes-3.0`

  • generate @octokit-next/types-openapi

  • rename @octokit-next/types-rest-api-github.com to @octokit-next/types-rest-api

  • generate @octokit-next/types-rest-api

  • generate diffs using xuorig/anicca: _diff files are now generated in octokit/openapi

  • generate @octokit-next/types-openapi-ghes-3.1 and @octokit-next/types-openapi-ghes-3.0

  • generate @octokit-next/types-rest-api-ghes-3.1 using @octokit-next/types-openapi-ghes-3.1

  • generate @octokit-next/types-rest-api-ghes-3.0 using @octokit-next/types-openapi-ghes-3.0

  • #29

  • update all the generated ghes-3.0.json (etc) OpenAPI files to include a "diff" key in "x-octokit": {}. The "diff" object is only present if there are any changes. All ghes-* versions other than the latest one should include a diff to the next GHES version, the rest should have a diff to github.com. Example:

    {
      "diff": {
        "github.com": {
          "type": "added" // "added" | "removed" | "changed"
        }
      }
    }
  • generate ghes-3.1.diff-to-api.github.com.json files (etc) based on ghes-3.1.anicca-diff-to-api.github.com.deref.json and ghes-3.1.json

    Remove all unchanged operations. Remove all orphaned components. Add operations that have been removed but with "responses": {} and "parameters": [], independent of the original specification. Set "description" to an explanation and set x-octokit.versions.removed to the current version. If "responses": {} is invalid, add a single 501 response (501 Not Implemented) with a useful "description": "..." property

  • use ghes-3.1.diff-to-api.github.com.json in @octokit-next/types-rest-api-ghes-3.1

  • use ghes-3.0.diff-to-api.github.com.json in @octokit-next/types-rest-api-ghes-3.0

Type generation broken

Due to the update of openapi-typescript in #100, the type generation broke

To remedy this, I propose we dry-run the type generation process whenever there's an update to openapi-typescript

See the logs:

file:///home/runner/work/octokit-next.js/octokit-next.js/node_modules/openapi-typescript/dist/load.js:141
    walk(options.schemas[schemaID].schema, (rawNode, nodePath) => {
                                   ^

TypeError: Cannot read properties of undefined (reading 'schema')
    at load (file:///home/runner/work/octokit-next.js/octokit-next.js/node_modules/openapi-typescript/dist/load.js:141:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Promise.all (index 0)
    at async load (file:///home/runner/work/octokit-next.js/octokit-next.js/node_modules/openapi-typescript/dist/load.js:187:5)
    at async openapiTS (file:///home/runner/work/octokit-next.js/octokit-next.js/node_modules/openapi-typescript/dist/index.js:37:5)
    at async run (file:///home/runner/work/octokit-next.js/octokit-next.js/scripts/types-openapi/update.js:91:7)

https://github.com/octokit/octokit-next.js/actions/runs/3430908885/jobs/5718425041

Make the `version` parameter work with the static `.withDefaults()` method

In a nutshell I want octokitGhes31_v1 and octokitGhes31_v2 to have both the internal version type set to "ghes-3.1."

const OctokitWithDefaultVersion = Octokit.withDefaults({ version: "ghes-3.1" });

const octokitGhes31_v1 = new OctokitWithDefaultVersion();
const octokitGhes31_v2 = new Octokit({ version: "ghes-3.1" });

Here is a TypeScript test file that should compile, but currently has several errors

import { Octokit } from "@octokit-next/core";

import "@octokit-next/types-rest-api-ghes-3.0";

export async function run() {
  const octokit = new Octokit({
    version: "ghes-3.1",
  });

  const response = await octokit.request("GET /ghes-only");

  expectType<boolean>(response.data.ok);

  const OctokitGHES31 = Octokit.withDefaults({
    version: "ghes-3.1",
  });
  const octokitGhes31 = new OctokitGHES31();
  expectType<never>(await octokitGhes31.request("GET /dotcom-only"));

  const octokitGhes30ViaConstructorOptions = new OctokitGHES31({
    version: "ghes-3.0",
  });
  expectType<never>(
    await octokitGhes30ViaConstructorOptions.request("GET /new-ghes-only")
  );

  const OctokitGHES30 = OctokitGHES31.withDefaults({
    version: "ghes-3.0",
  });
  const octokitGhes30ViaChainedDefaults = new OctokitGHES30();
  expectType<never>(
    await octokitGhes30ViaChainedDefaults.request("GET /new-ghes-only")
  );
}

function expectType<T>(value: T): void {}

Remove the `never` type for unsupported endpoints, require `{ request: { version }}` to be set instead

I had a thought today on how the types for the different APIs version might be more efficient and maybe more clear as well.

Right now, when using a route that is known but not supported by the current version, we use a type overload and the @deprecated flag to give a visual hint, and set the response type to never

image

This requires the GET /marketplace_listing/plans plans to be defined in @octokit-next/types-rest-api-ghes-3.2 as never:

  /**
   * The endpoint exists for github.com but does not exist for ghes-3.2
   */
  "GET /marketplace_listing/plans": never;

Instead of setting known routes to never, we can create a union of routes that are not implemented compared to the reference version and use that to filter them out when defining Octokit.ApiVersions[version]["Endpoints"]

I think what we should do instead is to make the request: { version }} parameter required for the GET /marketplace_listing/plans endpoint when the set version in context is ghes-3.2, and enforce version to be set to one of the versions that actually support it.

That way we need fewer overwrites for the octokit.request interface type, and the behavior is more TypeScript-y I think, in that it will not compile but give a useful error instead.

The other benefit is that "known routes" now go both ways. Not only will the IDE know all routes from github.com when the version is set to ghes-3.0, but also the other way around, which is currently not the case

I ran into this as I am working on the @octokit-next/endpoint package, with the full functionality of today's https://github.com/octokit/endpoint.js (and some more).

Make the Octokit constructor derive types for `octokit.request` based on the `version` option passed to the constructor

part of octokit/octokit.js#2127

Todos

  • #6
  • Add common response headers to github.com which may be extended / overwritten by ghes-3.1/ghes-3.0
  • Add a version parameter to the Octokit constructor which can only be set to github.com by default. But when importing the types for ghes-3.1, the version may also be set to ghes-3.1. When importing the types for ghes-3.0, the version parameter can be set to github.com, ghes-3.1, or ghes-3.0
  • Add .test-d.ts files to specify the desired behavior with the different types when setting the version on the Octokit constructor and the octokit.request method.
  • #9
  • Make the tests pass ๐Ÿ˜
  • #12

Differences between platforms

There are several differences between the REST API at https://api.github.com/ ("dotcom", GItHub Enterprise Server ("GHES") instances and GitHub AE ("GHAE").

  • Some endpoints will always only exist on one platform but not the other
  • New endpoints are always released on dotcom first, for example GET /app/hook/deliveries, which is not present in GHES 3.1 or older versions
  • Sometimes new parameters, response keys, or response headers are added to dotcom which do not propagate immediately to the other platforms
  • GHES includes a X-GitHub-Enterprise-Version response header

However there are no cases when an existing REST API endpoint behaves differently in a breaking way, the changes are only additive, e.g. when dotcom graduated a preview header which was not yet graduated on a GHES version.

Also if a script needs to be compatible with multiple GHES versions, it is enough to be compatible with the lowest version. What works in GHES 3.0 will also always work in GHES 3.1, 3.2, etc. At least within the range of officially supported GHES versions.

What we have today

Today we have types for all the 600+ REST API endpoints in dotcom. We do track the OpenAPI specifications for the other platforms in https://github.com/octokit/openapi and https://github.com/octokit/openapi-types.ts, but we don't use the other types in any @octokit modules yet.

We do have a plugin for GHES versions: https://github.com/octokit/plugin-enterprise-server.js. When loading the plugins, only the REST API methods are loaded that exist in the respective GHES version, but the types are incorrect. For example developers get TypeScript IntelliSense for non-existing parameters and response keys, while e.g. the GHES-only response headers are missing. And there are no types at all for the .admin.* endpoint methods, which makes the package unusable with TypeScript, as they build is failing. The TypeScript source code relies on REST API routes that do not exist in @octokit/types, so TypeScript will complain when attempting to build it. We have a long-staning open issue for this problem: octokit/plugin-enterprise-server.js#84

What we want

By default, The Ocotkit SDK should behave just as it does today:

const octokit = new Octokit({
  auth: env.GITHUB_TOKEN
})

const response = octokit.request("GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", {
  owner,
  repo,
  hook_id
})

Now in order to write script targeting a minimal GHES version, an optional version parameter can be set

const octokit = new Octokit({
  auth: env.GITHUB_TOKEN,
  version: "ghes-3.0"
})

const response = octokit.request("GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", {
  owner,
  repo,
  hook_id
})

The above code should not show a TypeScript error, explaining that the GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries endpoint is not present in GHES 3.1 and below.

On the other side, the response.headers type should now include { 'x-github-enterprise-version': string } in this example

const octokit = new Octokit({
  auth: env.GITHUB_TOKEN,
  version: "ghes-3.0"
})

const response = octokit.request("GET /")

while it wouldn't be set if the version option was set to "github.com" or not set at all.

So instead of creating entirely separate types for all the different platforms/versions, I think we should have the types built upon each other. The github.com version will include all the types we have today, then the ghes-3.1 endpoint types will extend the github.com endpoints add add its differences, e.g. sent some of the routes to never with a comment explaining that this endpoint is not availabil in GHES 3.1 and below, then ghes-3.0 will depend on ghes-3.1 and implement its differences, and so on.

Only the github.com types should be loaded by default. If a developer wants to build against ghes-3.0, they will have to install the respective types module and import it explicitly, e.g.

import { Octokit } from "octokit";
import "@octokit/types-endpoints-ghes-3.0";

const octokit = new Octokit({
  auth: env.GITHUB_TOKEN,
  version: "ghes-3.0"
})

const response = octokit.request("GET /")

That will import all necessary type differences between dotcom and GHES 3.1 as well as the differences between GHES 3.0 and 3.1

Compatibility versions

A common use case is to create code that is supposed to work against both dotcom and a minimal GHES version. For these cases we should create virtual compatibility versions, such as ghes-3.1-compatible, which would include types from both dotcom and GHES 3.1, but will flag the types that that do not exist in both as optional. So e.g. this code should throw errors

const octokit = new Octokit({
  auth: env.GITHUB_TOKEN,
  version: "ghes-3.0"
})

// error: `GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries` does not exist on GHES 3.1`
octokit.request("GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", {
  owner,
  repo,
  hook_id
})
// error: `x-github-enterprise-version` header does not exist on `dotcom`
const response = await octokit.request("GET /")
console.log(response.headers["x-github-enterprise-version"])

To resolve the above error, the version must be permitted to be set explicitly on the request

octokit.request("GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", {
  owner,
  repo,
  hook_id,
  request: { version: "github.com" },
})

const response = await octokit.request("GET /", { request: { version: "ghes-3.1" } })
console.log(response.headers["x-github-enterprise-version"])

Bonus: It would be nice if we could make the type code smart enough that e.g. checking for the presence of the x-github-enterprise-version header would work to set the version implicitly, so the code below wouldn't throw any errors.

const response = await octokit.request("GET /")
if ("x-github-enterprise-version" in response.headers) {
  // version is now implicitly set to `ghes-3.1`
  octokit.request("GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", { owner, repo, hook_id })
}

Plugins

Plugin developers are a special use case, as they want their plugins to be compatible explicitly with specific version. I'm not sure what the best approach would be, maybe it would suffice to add automated tests which would set version to all supported platform type versions, and then set a compatibility matrix as meta information on the plugin.

But either way, the least we need is to be able to explicitly set version on each request. That means that plugins might have their own dependency on endpoints type modules such as @octokit/types-endpoints-ghes-3.0. Not ideal as depending on one plugin which depends on an old version of @octokit/types-endpoints-ghes-* might result in a big amount of types-only dependencies, and even result loading outdated versions, so the app ends up having multiple versions of the types packages.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.