Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support hex v2 registry #29622

Open
rarkins opened this issue Jun 12, 2024 · 11 comments
Open

Support hex v2 registry #29622

rarkins opened this issue Jun 12, 2024 · 11 comments
Labels
datasource:hex priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others type:feature Feature (new functionality)

Comments

@rarkins
Copy link
Collaborator

rarkins commented Jun 12, 2024

Describe the proposed change(s).

Discussed in #24764

In order to support private registries, we need the hex datasource to support the hex v2 registry format described here: https://github.com/hexpm/specifications/blob/main/registry-v2.md

It seems that we should switch to using this registry protocol by default, including for the public registry.

@rarkins rarkins added type:feature Feature (new functionality) priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others datasource:hex labels Jun 12, 2024
@bryannaegele
Copy link
Contributor

How are the elixir/erlang versions set? And is it possible to include an elixir script to fetch the package info? That would make this very straightforward.

@rarkins
Copy link
Collaborator Author

rarkins commented Jun 13, 2024

No, we don't permit the calling of CLI tools as part of lookup

@bryannaegele
Copy link
Contributor

Ok. The suggestion here is to allow a script which is executed with mix run that is just fetching and decoding the list of releases from a registry. Everything needed is already available when installing elixir which is allowed in the mix manager but not currently done in the hex datasource. Hex is shipped as part of Elixir, so there are no other cli requirements.

The current methodology fetches json from an API and performs no validations. Using the registry, responses are protobuf encoded and include other features such as package signing verification. So our options for hex are to either leverage the functionality that ships with elixir for auth, fetching, decoding, and package signing verification or reimplement all of that functionality in TS.

I wasn't able to find any other datasources that are processing protobufs or protobuf related packages in core, so that would be a new addition.

So the proposal here is to let hex interact with hex registries in the hex datasource. Are there concerns or certain pieces of other functionality that are part of the current policy? We're trying to understand the reason for the policy if it pertains only to package lookup.

@bryannaegele
Copy link
Contributor

This is a very basic demo of the proposal.

https://gist.github.com/bryannaegele/4b9d11bc927d3887267028d1ea9f64f9

@rarkins
Copy link
Collaborator Author

rarkins commented Jun 13, 2024

We want datasources to be in TS so they can be used in the browser. Not other datasource requires binaries for lookups. If it's extremely hard it perhaps indicates that the registry should be made more accessible in future? Most are REST-based.

@viceice
Copy link
Member

viceice commented Jun 13, 2024

running external code for datasources will slow down the lookup phase massively, because we need to ensure to install a proper version of erlang and elixir. that is usually only done when we need to update lockfiles.

so I'm strictly against calling any binaries inside datasources.

There are official JavaScript libraries to decode protobuff messages easily.

@bryannaegele
Copy link
Contributor

Yep. Understandable. I'll get working on it

@bryannaegele
Copy link
Contributor

bryannaegele commented Jun 19, 2024

I'm pretty much done with this but running into one issue. In order to try and keep the previous amount of package detail with this change we have to make two calls. The first is to the registry, then a second to the API when it's hosted on hex.pm to get metadata. The hexpm registry and api are hosted on different domains (registry is a subdomain).

The issue I'm seeing when trying it locally with a private organization package hosted on hex, only the first call matches a hostRule and sets the auth token.

config

module.exports = {
  token: 'github_pat_**',
  repositories: ['simplebet/renovate-registry-test'],
  hostRules: [
    {
      matchHost: "https://hex.pm/api/repos/simplebet/",
      token: "org-token",
      authType: "Token-Only"
    },
    {
      matchHost: "https://repo.hex.pm/repos/simplebet/",
      token: "org-token",
      authType: "Token-Only"
    },
    {
      matchHost: "https://getoban.pro/repo",
      token: "oban-token",
      authType: "Token-Only",
    }
  ],
  registryAliases: {
    "oban": "https://getoban.pro/repo"
  }
};

log

DEBUG: Package registry url: https://repo.hex.pm/repos/simplebet/packages/private_package (repository=simplebet/renovate-registry-test)
DEBUG: hostRules: applying Bearer authentication for repo.hex.pm (repository=simplebet/renovate-registry-test)
DEBUG: Package metadata url: https://hex.pm/api/repos/simplebet/packages/private_package (repository=simplebet/renovate-registry-test)
DEBUG: GET https://hex.pm/api/repos/simplebet/packages/private_package = (code=ERR_NON_2XX_3XX_RESPONSE, statusCode=401 retryCount=0, duration=90) (repository=simplebet/renovate-registry-test)
DEBUG: Datasource unauthorized (repository=simplebet/renovate-registry-test)
       "datasource": "hex",
       "packageName": "org:simplebet:private_package",
       "url": "https://hex.pm/api/repos/simplebet/packages/private_package"
DEBUG: Failed to look up hex package org:simplebet:private_package (repository=simplebet/renovate-registry-test, packageFile=mix.exs, dependency=org:simplebet:private_package)

As you can see, a host rule is only applied to the first http call in getReleases. Is this expected behavior or a bug?

This does not crop up in unit tests.

it('processes a private organization repo with auth', async () => {
      httpMock
        .scope(baseRegistryUrl, {
          reqheaders: {
            authorization: 'abc',
          },
        })
        .get('/repos/private_org/packages/tls_certificate_check')
        .reply(200, tlsCertificateCheckRegistryResponse);

      httpMock
        .scope(baseHexpmUrl, {
          reqheaders: {
            authorization: 'abc',
          },
        })
        .get('/repos/private_org/packages/tls_certificate_check')
        .reply(200, tlsCertificateCheckAPIResponse);

      hostRules.find.mockReturnValue({
        authType: 'Token-Only',
        token: 'abc',
      });
      const result = await getPkgReleases({
        ...config,
        packageName: 'org:private_org:tls_certificate_check',
      });

      expect(result).not.toBeNull();
    });

@rarkins
Copy link
Collaborator Author

rarkins commented Jun 24, 2024

log

DEBUG: Package registry url: https://repo.hex.pm/repos/simplebet/packages/private_package (repository=simplebet/renovate-registry-test)
DEBUG: hostRules: applying Bearer authentication for repo.hex.pm (repository=simplebet/renovate-registry-test)
DEBUG: Package metadata url: https://hex.pm/api/repos/simplebet/packages/private_package (repository=simplebet/renovate-registry-test)
DEBUG: GET https://hex.pm/api/repos/simplebet/packages/private_package = (code=ERR_NON_2XX_3XX_RESPONSE, statusCode=401 retryCount=0, duration=90) (repository=simplebet/renovate-registry-test)
DEBUG: Datasource unauthorized (repository=simplebet/renovate-registry-test)
       "datasource": "hex",
       "packageName": "org:simplebet:private_package",
       "url": "https://hex.pm/api/repos/simplebet/packages/private_package"
DEBUG: Failed to look up hex package org:simplebet:private_package (repository=simplebet/renovate-registry-test, packageFile=mix.exs, dependency=org:simplebet:private_package)

As you can see, a host rule is only applied to the first http call in getReleases. Is this expected behavior or a bug?

FYI you should see that log messageabout applying authentication once per host, not once per request.

Based on your hostRules, I would expect the auth to be applied to https://hex.pm too

@bryannaegele
Copy link
Contributor

Ah. I didn't catch that. I think that could present an edge case if a user needed to auth to multiple orgs but that isn't the case in the example repo. I'll dig into this.

@bryannaegele
Copy link
Contributor

Works today 🤷🏻 . I'll mark the PRs ready for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
datasource:hex priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others type:feature Feature (new functionality)
Projects
None yet
Development

No branches or pull requests

3 participants