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

Differing behaviour retrieving gitlab-tags and releases between datasource and changelog #13497

Closed
rv2673 opened this issue Jan 11, 2022 · 7 comments · Fixed by #13695
Closed
Labels
status:requirements Full requirements are not yet known, so implementation should not be started type:bug Bug fix of existing functionality

Comments

@rv2673
Copy link
Contributor

rv2673 commented Jan 11, 2022

How are you running Renovate?

Self-hosted

If you're self-hosting Renovate, tell us what version of Renovate you run.

31.22.1

Please select which platform you are using if self-hosting.

gitlab.com

If you're self-hosting Renovate, tell us what version of the platform you run.

gitlab.com

Describe the bug

When configuring hostRules for gitlab-tags to make retrieval of tags of a private repository I ran into issues. The tags can be succesfully retrieved however soon after that when renovate tries to retrieve the changelogs by querying the same repository (tags, changelog md or releases) it fails since the same hostrules don't apply.

Created reproduction on gitlab(when doing so on github, the gitlab-tags datasource starts using github api, but that is different issue).

  • Private repository with template which are tagged(not publicy visible(otherwise it won't work))
  • Public project to be renovated
  • Gitlab runner project containing pipeline doing renovate. (Configured to renovate public project, renovate token has access to public project, hostrules configured with token with access to private repository)

In the case where I ran into this, it is not possible to have the permission for the private repository added to the global RENOVATE_TOKEN used for the runner.

I did some debugging and I think the following are the causes preventing this from being possible:

  • The way the url is created for the gitlab api calls is different for changelog tags and gitlab-tags datsource. The repoName is encoded differently in both cases(one encoding function, resulting in uppercase escapes and the other regex replace with lowercase escapes). (see here and here). (This can be worked around by adding the rule twice with slightly different matchHost)
  • The gitlab-tags hostRule doesn't apply because all the changelog calls use the 'gitlab' hostType. While the gitlab-tags datasource use the 'gitlab-tags' hostType.
  • A hostrule for hostType 'gitlab' is ineffective since the default rule for gitlab hostype that is added is added to the end of the list when loading the configuration after all the user specified rules.

I would be happy to create a PR for a fix, but what would be the best way to proceed?
What I can think of is the following, but I don't have the complete picture.:

  • Move the gitlab default rule to the before the user defined ones after the default timeout rule.
  • Make the urlencoding the same in both locations
  • Add hostTypes for each of of the changelog requests

Relevant debug logs

Logs [Runner job logs](https://gitlab.com/renovate-reproduction-test/renovate-reproduction-runner/-/jobs/1964027168)

Section which I think is relevant, added below

 INFO: Dependency extraction complete (repository=renovate-reproduction-test/renovate-reproduction-project)
       "baseBranch": "main",
       "stats": {
         "managers": {"gitlabci-include": {"fileCount": 1, "depCount": 1}},
         "total": {"fileCount": 1, "depCount": 1}
       }
DEBUG: Package releases lookups complete (repository=renovate-reproduction-test/renovate-reproduction-project)
       "baseBranch": "main"
DEBUG: branchifyUpgrades (repository=renovate-reproduction-test/renovate-reproduction-project)
DEBUG: 1 flattened updates found: renovate-reproduction-test/private-template-repo-example (repository=renovate-reproduction-test/renovate-reproduction-project)
DEBUG: Returning 1 branch(es) (repository=renovate-reproduction-test/renovate-reproduction-project)
DEBUG: Fetching changelog: https://gitlab.com/renovate-reproduction-test/private-template-repo-example (1.0.0 -> 1.1.0) (repository=renovate-reproduction-test/renovate-reproduction-project)
DEBUG: GitLab API 404 (repository=renovate-reproduction-test/renovate-reproduction-project)
       "url": "https://gitlab.com/api/v4/projects/renovate-reproduction-test%2fprivate-template-repo-example/repository/tags?per_page=100"
DEBUG: Failed to fetch Gitlab tags (repository=renovate-reproduction-test/renovate-reproduction-project)
       "sourceRepo": "renovate-reproduction-test/private-template-repo-example",
       "err": {
         "name": "HTTPError",
         "code": "ERR_NON_2XX_3XX_RESPONSE",
         "timings": {
           "start": 1641927732532,
           "socket": 1641927732532,
           "lookup": 1641927732533,
           "connect": 1641927732545,
           "secureConnect": 1641927732558,
           "upload": 1641927732559,
           "response": 1641927733956,
           "end": 1641927733957,
           "phases": {
             "wait": 0,
             "dns": 1,
             "tcp": 12,
             "tls": 13,
             "request": 1,
             "firstByte": 1397,
             "download": 1,
             "total": 1425
           }
         },
         "message": "Response code 404 (Not Found)",
         "stack": "HTTPError: Response code 404 (Not Found)\n    at Request.<anonymous> (/usr/src/app/node_modules/got/dist/source/as-promise/index.js:117:42)\n    at processTicksAndRejections (internal/process/task_queues.js:95:5)",
         "options": {
           "headers": {
             "user-agent": "RenovateBot/31.22.1 (https://github.com/renovatebot/renovate)",
             "authorization": "***********",
             "accept": "application/json",
             "accept-encoding": "gzip, deflate, br"
           },
           "url": "https://gitlab.com/api/v4/projects/renovate-reproduction-test%2fprivate-template-repo-example/repository/tags?per_page=100",
           "hostType": "gitlab",
           "username": "",
           "password": "",
           "method": "GET",
           "http2": false
         },
         "response": {
           "statusCode": 404,
           "statusMessage": "Not Found",
           "body": {"message": "404 Project Not Found"},
           "headers": {
             "date": "Tue, 11 Jan 2022 19:02:13 GMT",
             "content-type": "application/json",
             "content-length": "35",
             "connection": "close",
             "cache-control": "no-cache",
             "vary": "Origin",
             "x-content-type-options": "nosniff",
             "x-frame-options": "SAMEORIGIN",
             "x-request-id": "01FS589VC1QW6BBXGNNR08BQC9",
             "x-runtime": "0.165586",
             "strict-transport-security": "max-age=31536000",
             "referrer-policy": "strict-origin-when-cross-origin",
             "ratelimit-observed": "6",
             "ratelimit-remaining": "1994",
             "ratelimit-reset": "1641927793",
             "ratelimit-resettime": "Tue, 11 Jan 2022 19:03:13 GMT",
             "ratelimit-limit": "2000",
             "gitlab-lb": "fe-16-lb-gprd",
             "gitlab-sv": "localhost",
             "cf-cache-status": "DYNAMIC",
             "expect-ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"",
             "report-to": "{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=%2Bh90%2BcNBUq1D%2FCR%2BePhCBHVgJ0oYPArr%2Bb5QRGMvhTJaMmLZd0g%2B8j4TgwTTajxo2D15oOV34xETCkoq%2Fqs1S222LrRXXIlHCgPySuMo6sixCCKwrGnLexTSHfI%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}",
             "nel": "{\"success_fraction\":0.01,\"report_to\":\"cf-nel\",\"max_age\":604800}",
             "server": "cloudflare",
             "cf-ray": "6cc065e88f938d42-ATL"
           },
           "httpVersion": "1.1"
         }
       }
DEBUG: GitLab API 404 (repository=renovate-reproduction-test/renovate-reproduction-project)
       "url": "https://gitlab.com/api/v4/projects/renovate-reproduction-test%2fprivate-template-repo-example/repository/tree?per_page=100"
DEBUG: Error 404 getting changelog md (repository=renovate-reproduction-test/private-template-repo-example)
       "type": "gitlab",
       "apiBaseUrl": "https://gitlab.com/api/v4/"
DEBUG: GitLab API 404 (repository=renovate-reproduction-test/renovate-reproduction-project)
       "url": "https://gitlab.com/api/v4/projects/renovate-reproduction-test%2fprivate-template-repo-example/releases?per_page=100"
DEBUG: getReleaseList 404 (repository=renovate-reproduction-test/private-template-repo-example)
       "type": "gitlab",
       "apiBaseUrl": "https://gitlab.com/api/v4/"
DEBUG: config.repoIsOnboarded=true (repository=renovate-reproduction-test/renovate-reproduction-project)
DEBUG: packageFiles with updates (repository=renovate-reproduction-test/renovate-reproduction-project)
       "config": {
         "gitlabci-include": [
           {
             "packageFile": ".gitlab-ci.yml",
             "deps": [
               {
                 "datasource": "gitlab-tags",
                 "depName": "renovate-reproduction-test/private-template-repo-example",
                 "depType": "repository",
                 "currentValue": "1.0.0",
                 "registryUrls": ["https://gitlab.com"],
                 "depIndex": 0,
                 "updates": [
                   {
                     "bucket": "non-major",
                     "newVersion": "1.1.0",
                     "newValue": "1.1.0",
                     "releaseTimestamp": "2022-01-08T15:11:27.000Z",
                     "newMajor": 1,
                     "newMinor": 1,
                     "updateType": "minor",
                     "branchName": "renovate/renovate-reproduction-test-private-template-repo-example-1.x"
                   }
                 ],
                 "warnings": [],
                 "versioning": "semver",
                 "sourceUrl": "https://gitlab.com/renovate-reproduction-test/private-template-repo-example",
                 "currentVersion": "1.0.0",
                 "isSingleVersion": true,
                 "fixedVersion": "1.0.0"
               }
             ]
           }
         ]
       }

Have you created a minimal reproduction repository?

I have linked to a minimal reproduction repository in the bug description

@rv2673 rv2673 added priority-5-triage status:requirements Full requirements are not yet known, so implementation should not be started type:bug Bug fix of existing functionality labels Jan 11, 2022
@rarkins
Copy link
Collaborator

rarkins commented Jan 14, 2022

I think this can be fixed first/independently:

The way the url is created for the gitlab api calls is different for changelog tags and gitlab-tags datsource.

For the second point, are you adding any hostRules for the private repo manually, or is it only the automatic rules generated from your renovate token?

@rv2673
Copy link
Contributor Author

rv2673 commented Jan 14, 2022

I have added the following rules manually.

module.exports = {
    hostRules: [
        {
            "matchHost": "https://gitlab.com/api/v4/projects/renovate-reproduction-test%2Fprivate-template-repo-example",
            "authType": "Bearer",
            "token": process.env["READONLY_GITLAB_LOOKUP_TOKEN"]
        }
    ]
};

During debugging locally by adding some additional log statement(No longer have the logs, but will see if can rerun later today for completeness) I noticed the following rules in the resulting hostRules that is being applied to the requests:

  • Automatically generated default rule with timeout and no match conditions.
  • All the user specified rules (the above)
  • The automatically generated gitlab rule (with gitlab hostType and gitlab.com matcHost)

I also tried also adding the following rule besides the one above.

module.exports = {
    hostRules: [
        {
            "hostType: "gitlab",
            "matchHost": "https://gitlab.com/api/v4/projects/renovate-reproduction-test%2Fprivate-template-repo-example",
            "authType": "Bearer",
            "token": process.env["READONLY_GITLAB_LOOKUP_TOKEN"]
        }
    ]
};

But since the automatically generated one is always last in the list, it also always is applied as the last multi rule(both hostType and hostName match). Making the above rule ineffective.

@rarkins
Copy link
Collaborator

rarkins commented Jan 14, 2022

OK, so your best guess right now is that it's caused by the ordering of hostRules? I think it makes sense that globally configured hostRules should be after any automatic ones, but I'm not sure how easy or elegantly that could be changed.

@viceice
Copy link
Member

viceice commented Jan 14, 2022

I think we need to use unshift instead of push to get the at beginning here:

returnConfig.hostRules.push(typedPlatformRule);
hostRules.add(typedPlatformRule);

Not sure how to handle the second line. Maybe clear and readd all rules?

@rarkins
Copy link
Collaborator

rarkins commented Jan 14, 2022

Maybe time for a code inspection and refactor to determine why we don't have a single source of truth already and if it can be made better.

@rv2673
Copy link
Contributor Author

rv2673 commented Jan 16, 2022

I have looked at the code a bit more. While the ordering of the rules might be a bit confusing it indeed might be undesirable to override platform authentication (RENOVATE_TOKEN), which is probably why the rule is added at end.

The main cause I think is actually that non platform calls like getting changelog for a release/dependency use the platform identifier as hostType, making it indistinguishable from platform calls(getting user, checking out repo, pushing MR).
That is probably why gitlab tags and gitlab-releases override this default hostType on the GitlabHttp instance they use.

That way it can be overridden by a hostType specific host rule and the hostrules code already contains a fallback to gitlab hostype if there are no rules for the specific type.

I just locally implemented and tested a solution where I added a 'gitlab-changelog' host type to the changelog calls instead of the default 'gitlab' and added it to the fallback types.
Which makes it possible to apply hostRules to the calls, and if none configured it automatically falls back to gitlab hostype with the automatically added rule.

I also noticed when looking through the code, that this same issue probably exists for gitlab-packages datasource, since it also doesn't set the hostType in calls as far as I can tell.

Will create a PR for these fixes.

@renovate-release
Copy link
Collaborator

🎉 This issue has been resolved in version 31.66.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status:requirements Full requirements are not yet known, so implementation should not be started type:bug Bug fix of existing functionality
Projects
None yet
4 participants