semantic-release / gitlab

:fox_face: semantic-release plugin to publish a GitLab release
MIT License
269 stars 78 forks source link

fix: adds some guards around branch name #671

Closed phpboyscout closed 3 weeks ago

phpboyscout commented 5 months ago

There are scenarios where branch is not an object in the get-fail-commit function To protect against this we add a few guards in the event that it could be any of an object a string or undefined

JonasSchubert commented 5 months ago

Hi @phpboyscout and thanks for your contribution. Can you elaborate which scenarios this might be where branch is not an object? If this is the case this might need some deeper fix in semantic-release as it would possibly affect many other plugins then. According to the docs the branch should always be set.

phpboyscout commented 5 months ago

Hi @JonasSchubert that is what I assumed as well at first. I've used this plugin many times without issue. However, when using it recently at a company using Gitlab SaaS with self-hosted Runners we consistently found that we would get an error thrown when trying to access branch.name this caused several issues for us. When debugging we found that regardless of the configuration we used we would consistently get this issue. We traced it back to what seemed to be Semantic Release itself sending a string rather than an object... Our solution, albeit temporary, was to fork and fix this by adding these guards, which obviously only cures the symptom but unblocked us from moving forward without having to dig into delve too deeply into semantic release itself. We experienced this version pretty consistently with version 22.0.12. We have not tested to see if its still present in 23.0.0

JonasSchubert commented 5 months ago

Can you publish your configuration and if possible also some logs?\ And are you using additional plugins to @semantic-release/gitlab?

For example @semantic-release/git is using branch.name, too. (You are not using it, but semantic-release/github has similar code to this plugin and could also be affected then)

And can you pin down the version of semantic release where it was still working?

phpboyscout commented 5 months ago

Unfortunately, I can't pin down the specific version where it was last working. That was at a previous company and I no longer have access to those records.

Below is the config and resulting output... the root cause of this output was a filesystem permission issue but if you look at line 18 you can see the issue with the branch name

[10:18:58 AM] [semantic-release] › ℹ  Running semantic-release version 22.0.12
(node:38) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "verifyConditions" from "semantic-release-helm"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "verifyConditions" from "@semantic-release/git"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "verifyConditions" from "@phpboyscout/semantic-release-gitlab"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "analyzeCommits" from "@phpboyscout/semantic-release-commit-analyzer"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "generateNotes" from "@phpboyscout/scoped-release-notes-generator"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "prepare" from "semantic-release-helm"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "prepare" from "@semantic-release/git"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "publish" from "semantic-release-helm"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "publish" from "@phpboyscout/semantic-release-gitlab"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "success" from "@phpboyscout/semantic-release-gitlab"
[10:19:01 AM] [semantic-release] › ✔  Loaded plugin "fail" from "@phpboyscout/semantic-release-gitlab"
[10:19:01 AM] [semantic-release] › ℹ  Start step "fail" of plugin "@phpboyscout/semantic-release-gitlab"
[10:19:01 AM] [semantic-release] [@phpboyscout/semantic-release-gitlab] › ℹ  Verify GitLab authentication (https://gitlab.com/api/v4)
[10:19:02 AM] [semantic-release] › ✘  Failed step "fail" of plugin "@phpboyscout/semantic-release-gitlab"
[10:19:02 AM] [semantic-release] › ✘  An error occurred while running semantic-release: TypeError: Cannot read properties of undefined (reading 'name')
    at default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/@phpboyscout/semantic-release-gitlab/lib/get-fail-comment.js:20:10)
    at default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/@phpboyscout/semantic-release-gitlab/lib/fail.js:29:83)
    at fail (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/@phpboyscout/semantic-release-gitlab/index.js:39:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async validator (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/plugins/normalize.js:36:24)
    at async file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/plugins/pipeline.js:38:36
    at async file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/plugins/pipeline.js:32:5
    at async pluginsConfigAccumulator.<computed> [as fail] (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/plugins/index.js:87:11)
    at async callFail (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:2[49](https://gitlab.com/mangopay/sre/cluster-charts/-/jobs/5851632811#L49):7)
    at async Module.default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:279:7) {
  pluginName: '@phpboyscout/semantic-release-gitlab'
}
[10:19:02 AM] [semantic-release] › ✘  ENOGITREPO Not running from a git repository.
The semantic-release command must be executed from a Git repository.
The current working directory is /builds/mangopay/sre/cluster-charts.
Please verify your CI configuration to make sure the semantic-release command is executed from the root of the cloned repository.
AggregateError: 
    SemanticReleaseError: Not running from a git repository.
        at default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/get-error.js:6:10)
        at default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/verify.js:15:17)
        at async run (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:65:3)
        at async Module.default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:275:22)
        at async default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/cli.js:[55](https://gitlab.com/mangopay/sre/cluster-charts/-/jobs/5851632811#L55):5)
    at default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/verify.js:41:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async run (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:[65](https://gitlab.com/mangopay/sre/cluster-charts/-/jobs/5851632811#L65):3)
    at async Module.default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:275:22)
    at async default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/cli.js:55:5) {
  errors: [
    SemanticReleaseError: Not running from a git repository.
        at default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/get-error.js:6:10)
        at default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/lib/verify.js:15:17)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
        at async run (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:65:3)
        at async Module.default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/index.js:275:22)
        at async default (file:///usr/local/nvm/versions/node/v21.5.0/lib/node_modules/semantic-release/cli.js:55:5) {
      code: 'ENOGITREPO',
      details: 'The `semantic-release` command must be executed from a Git repository.\n' +
        '\n' +
        'The current working directory is `/builds/mangopay/sre/cluster-charts`.\n' +
        '\n' +
        'Please verify your CI configuration to make sure the `semantic-release` command is executed from the root of the cloned repository.',
      semanticRelease: true
    }
  ]
}

The config for this run is as follows

{
  "plugins": [
    ["@phpboyscout/semantic-release-commit-analyzer",{
      "ignoreDefaultRules": true,
      "releaseRules": [
        { "scope": "cert-manager", "breaking": true, "release": "major" },
        { "scope": "cert-manager", "type": "feat", "release": "minor" },
        { "scope": "cert-manager", "release": "patch" }
      ]
    }],
    ["@phpboyscout/scoped-release-notes-generator",{
      "scope": "cert-manager"
    }],
    ["semantic-release-helm", {
        "chartPath": "charts/${scope}/",
        "onlyUpdateVersion": true
    }],
    ["@semantic-release/git", {
      "assets": ["charts/${scope}/Chart.yaml"],
      "message": "chore(release): ${nextRelease.version} \n\n${nextRelease.notes}"
    }],
    "@phpboyscout/semantic-release-gitlab"
  ],
  "branches": [
    "main",
    "ExtendedMonitoringCharts-8677f3key"
  ],
  "tagFormat": "cert-manager_${version}"
}

We have a number of plugins we are using including some internal ones to helm with management of a monorepo. All of them listed in the config above

JonasSchubert commented 5 months ago

Thanks for the logs @phpboyscout . The file permission issue seems to be the problem here overall. It looks like semantic-release was not able to retrieve branch information because no git repository was accessible. I am not sure whether it is a good approach to build a workaround for branch here, as other important information might be missing, too. After you resolved the file permission issues, did you still encounter the error?

JonasSchubert commented 5 months ago

To fail early, we could add an additional check in the verify step - to validate whether we are running in a git repository, whether we have all relevant information (branch, project url,...),.., But this would be redundant to the git plugin.

phpboyscout commented 5 months ago

Hi @JonasSchubert, in all honesty I cant say that I have seen it since the permissions issue was resolved, we had quite a few threads we were pulling at the same time.

I would suggest that having some form of check to "gracefully" exit rather than get the double error that we were presented with would be beneficial. As it did leave us scratching our heads at the time and it caused a hard stop, with an erroneous error because it didn't handle that scenario properly...

When we applied this change to our local fork it meant that it would gracefully fail the task, present us with the correct ENOGITREPO Not running from a git repository error and also raise an issue in Gitlab accordingly mentioning an "unknown" branch.

JonasSchubert commented 4 months ago

Agreed. Do you think an additional verify check would fulfill your requirements? @fgreinacher what do you think?

fgreinacher commented 4 months ago

Maybe look at how the GitHub plugin handles this case.

In general I think one error message for the root case should be enough 😀

fgreinacher commented 3 weeks ago

I'm closing this because it is only a very local workaround.

Feel free to create follow-up issues/PRs to improve the overall behavior in error cases!