{"id":23651901,"url":"https://github.com/microfocus/octane-gitlab-service","last_synced_at":"2025-09-01T02:32:13.347Z","repository":{"id":35913182,"uuid":"154140235","full_name":"MicroFocus/octane-gitlab-service","owner":"MicroFocus","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-03T18:48:45.000Z","size":449,"stargazers_count":3,"open_issues_count":9,"forks_count":12,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-07-30T01:48:04.295Z","etag":null,"topics":["octane"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MicroFocus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-22T12:30:25.000Z","updated_at":"2024-09-13T10:17:11.000Z","dependencies_parsed_at":"2024-03-05T17:01:20.113Z","dependency_job_id":"3d732e2e-4334-40b2-bcd5-08883d315b44","html_url":"https://github.com/MicroFocus/octane-gitlab-service","commit_stats":null,"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/MicroFocus/octane-gitlab-service","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MicroFocus%2Foctane-gitlab-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MicroFocus%2Foctane-gitlab-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MicroFocus%2Foctane-gitlab-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MicroFocus%2Foctane-gitlab-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MicroFocus","download_url":"https://codeload.github.com/MicroFocus/octane-gitlab-service/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MicroFocus%2Foctane-gitlab-service/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273065038,"owners_count":25039274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["octane"],"created_at":"2024-12-28T16:48:55.320Z","updated_at":"2025-09-01T02:32:13.019Z","avatar_url":"https://github.com/MicroFocus.png","language":"Java","readme":"![OPENTEXT LOGO](https://upload.wikimedia.org/wikipedia/commons/1/1b/OpenText_logo.svg)\n\n[![Build status](https://ci.appveyor.com/api/projects/status/github/MicroFocus/octane-gitlab-service?branch=master\u0026svg=true)](https://ci.appveyor.com/project/OctaneCIPlugins/octane-gitlab-service)\n\n## Relevant links\n\n-\t**Download the most recent LTS version of the service** at [Github releases](https://github.com/MicroFocus/octane-gitlab-service/releases)\n-\t**Check the open issues (and add new issues)** at [Github issues](https://github.com/MicroFocus/octane-gitlab-service/issues)\n\n\n# ALM Octane GitLab CI service\n\nThis service integrates ALM Octane with GitLab, enabling ALM Octane to display GitLab build pipelines and track build and test run results.\n\n\n#### Integration flow:\n\nThe service communicates both with the GitLab server and the Octane server.\nBoth sides of communication must be reachable. \n\n##### Communication with Gitlab:\n\n* The service sends an API requests to GitLab server.  \nFor example: check permission, get project list, get test results, run project.  \n\n* GitLab sends events to this service.  \nFor example: start and finish running of project.  \nThe service registers to events using the GitLab project webhook mechanism.\n\n_**Note that if the service is down or unavailable, the data will be lost and not displayed in ALM Octane.**_  \n\n\n\n##### Communication with Octane:\n\nThe service makes use of the Octane [CI SDK](https://github.com/MicroFocus/octane-ci-java-sdk) for sending CI events to ALM Octane (pipeline started/job started/SCM data etc.).\n\n\n\n\n## Installation and configuration instructions\n\n1. Create a new directory to serve as the installation target, hosted on any machine that can access GitLab. (If GitLab is behind a firewall, this machine must also be behind it.)\n2. Download the octane-gitlab-service-\\\u003cversion\\\u003e.jar file from the release assets and copy it to the target directory.\n3. In ALM Octane, create an API access Client ID and Client secret with the CI/CD Integration role.\n4. In GitLab, create a personal access token with read/write over API and read over repository scopes for the integration user. The integration user should have a MAINTAINER role inside the projects/groups which you want to integrate in ALM Octane.\n5. In the target directory create a new application.properties file. Populate it with the following properties, and modify the placeholders with the appropriate values.\n```application.properties\n# Jetty oriented properties\n# =========================\nserver.port=9091\n\n\n# ALM Octane GitLab Service-oriented properties\n# =========================================\nserver.baseUrl=\u003cmandatory: the base URL of this service (the URL on which the GitLab service actually runs), should be accessible by GitLab\u003e\nserver.webhook.route.url=\u003coptional: the webhook URL of the GitLab service that can be exposed and is reachable from GitLab (the URL that GitLab will send events to)\u003e\nciserver.identity=\u003coptional: CI server identity, by default a hash value generated from the service URL is used\u003e\noctane.location=\u003cmandatory: the URL of the ALM Octane server with the /ui path and the sharedspace parameters. Example: https://myserver:8080/ui?p=1005\u003e\noctane.apiClientID=\u003cmandatory: ALM Octane API client ID with CI/CD integration role over the target workspace(s)\u003e\noctane.apiClientSecret=\u003csensitive,mandatory: ALM Octane API client secret\u003e\ngitlab.location=\u003cmandatory: the base URL of the GitLab server\u003e\ngitlab.personalAccessToken=\u003csensitive,mandatory: GitLab personal access token\u003e\ngitlab.testResultsFilePattern=\u003coptional: 'glob:pattern' or 'regex:pattern' pattern for finding the test result files inside GitLab job artifact ZIP\u003e.\nFor complete documentation of the applicable patterns see https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-\ngitlab.gherkinTestResultsFilePattern=\u003coptional:'glob:pattern' or 'regex:pattern' pattern for finding Gherkin test result files inside GitLab job artifact ZIP\u003e\ngitlab.testResultsOutputFolderPath=\u003coptional: place to save test results before sending it to Octane.\u003e\ngitlab.variables.pipeline.usage=\u003coptional: comma separated list of project,groups,instance\u003e\ngitlab.ci.service.can.run.pipeline=\u003coptional: If the service can run pipelines from ALM Octane. true by default\u003e\n\ngitlab.codeCoverage.generatedCoverageReportFilePathVarName=\u003coptional: Name of the variable containing the path of the generated JaCoCo coverage report file as configured in the pipeline. Default value: jacocoReportPath\u003e\ngitlab.mergeRequests.variables.publishMergeRequestVarName=\u003coptional: Name of the variable containing a boolean value that specifies if merge requests will be published into Octane from the current project. Default value: 'publishMergeRequests'\u003e\ngitlab.mergeRequests.variables.destinationWorkspaceVarName=\u003coptional: Name of the variable containing a string value that specifies the destination workspace id where merge requests will be published into Octane from the current project. Default value: 'destinationWorkspace'\u003e\ngitlab.mergeRequests.variables.useSSHFormatVarName=\u003coptional: Name of the variable containing a boolean value that specifies if the clone url for the current proeject should be in SSH format or not. Default value: 'useSSHFormat'\u003e\ngitlab.mergeRequests.mergeRequestHistoryFolderPath=\u003coptional: Path of directory to store fetch history state for projects. Default value: 'projectHistory'\u003e\n\n# HTTP(S) proxy oriented properties\n# =================================\n#http.proxyUrl=\u003coptional: http proxy URL\u003e\n#http.proxyUser=\u003coptional: http proxy username\u003e\n#http.proxyPassword=\u003csensitive,optional: http proxy password\u003e\n#http.nonProxyHosts=\u003coptional: comma separated list of hosts to access without the http proxy\u003e\n#https.proxyUrl=\u003coptional: https proxy URL\u003e\n#https.proxyUser=\u003coptional: https proxy username\u003e\n#https.proxyPassword=\u003csensitive,optional: https proxy password\u003e\n#https.nonProxyHosts=\u003coptional: comma separated list of hosts to access without the https proxy\u003e\n```\n6. From a command line prompt open on the target directory, run the command line below:\n```bash\njava –jar octane-gitlab-service-\u003cversion\u003e.jar\n```\n\n### Properties information:\n\n##### server.port\nThe TCP port for this service to listen on.\n\n##### server.baseUrl\nThe base URL of this service should be accessible by GitLab.\n\nExample:\n\n    http://myServiceServer.myCompany.com:9091\n\n##### server.webhook.route.url\nIf GitLab is in another network and can't access \u003cserver.baseUrl\u003e\\events, insert here the accessible URL\nand route this **\u003cserver-based URL\u003e\\events** to **\u003cserver-based URL\u003e\\events**.\n\n##### ciserver.identity\nThe identity of the GitLab server in the ALM Octane server. By default, a hash value generated from the service URL is used.\nOverriding this property is helpful in preserving the CI server identity while migrating GitLab to another location.\n\n##### octane.location\nThe URL of the ALM Octane server, using its fully qualified domain name (FQDN).\n\nUse the following format (port number is optional):\n\n    http://\u003cALM Octane hostname / IP address\u003e {:\u003cport number\u003e}/ui/?p=\u003cshared space ID\u003e\n\nExample:  \nIn this URL, the shared space ID is 1002:\n\n    http://myALMOctaneServer.myCompany.com:8081/ui/?p=1002\n\n**Tip: You can copy the URL from the address bar of the browser in which you opened ALM Octane.**\n\n##### octane.apiClientID\nThe API access Client ID that the plugin should use to connect to ALM Octane.\n##### octane.apiClientSecret\nThe API Client secret that the plugin should use to connect to ALM Octane. This is a sensitive token. See the 'Password Encryption' section below.\n##### gitlab.location\nThe base URL of GitLab.\nExample:\n\n    http://myGitLabServer.myCompany.com:30080\n##### gitlab.personalAccessToken\nA personal access token for a particular user in GitLab, the user should be a member of the projects/group with MAINTAINER rights, and the scopes of the token should be read/write over API and read over repository. This is a sensitive token. See the 'Password Encryption' section below.\n##### gitlab.testResultsFilePattern\nA 'glob:pattern' or 'regex:pattern' pattern for finding the test result files inside GitLab job artifact ZIP.\nFor complete documentation about the applicable patterns see [java.nio.file.FileSystem::getPathMatcher](https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-)\nNote: In order to report test results to ALM Octane, a GitLab job must add the test results file into its artifacts at a path that matches this pattern.\nExample (any XML file recursively):\n\n     glob:**.xml\n\n##### gitlab.gherkinTestResultsFilePattern #####  \nSame as testResultsFilePattern property, but for Gherkin test results.\n\n##### gitlab.testResultsOutputFolderPath #####\nPath to directory in GitLab service machine, where Gherkin test results will be stored until sent to Octane. \nAfter one hour the files will be deleted. \n    \n##### gitlab.variables.pipeline.usage\nBy default, the service report to ALM Octane includes all of the project's variables.  \nThese variables will be present in the Pipeline module and the user can set new values for them and run the pipeline from ALM Octane.\n\nTo also see the groups or instance variables, add them to the property’s value.\nExample:   \n       \n* Variables from project: gitlab.variables.pipeline.usage=project   \n\n* Variables from project, groups and from instance: gitlab.variables.pipeline.usage=project,groups,instance\n  \n* Variables from group only: gitlab.variables.pipeline.usage=groups\n\n##### gitlab.ci.service.can.run.pipeline\nBy default, the user can also run pipelines from ALM Octane.\nWhen ALM Octane users are not allowed to trigger the pipeline, the parameter should be set to 'false'. \n\n##### gitlab.mergeRequests.variables.publishMergeRequestVarName\nThe name of the GitLab variable that specifies if merge requests should be sent to Octane or not for the project where\nthe variable is defined.\n\nThe values must be boolean (true or false).\n\nIf the variable is not defined in Gitlab or if it is set to anything but true then merge requests will not be sent to \nOctane for the current project.\n\n##### gitlab.mergeRequests.variables.destinationWorkspaceVarName\nThe name of the GitLab variable that specifies the destination workspace id for the merge requests.\n\nIf the project has merge request sending set to true (the publishMergeRequest variable) but does not have this variable\ndefined or if the workspace id specified does not exist an error will be thrown.\n\nRule of thumb: Where publishMergeRequest variable is set to true, destinationWorkspace variable must also be configured \nin order for the tool to work correctly.\n\n##### gitlab.mergeRequests.variables.useSSHFormatVarName\nThe name of the GitLab variable that specifies which URL of the repository should be used for cloning.\n\nThe values must be boolean (true or false).\n\nIf the value is set to true, the ssh URL will be used. Otherwise, if the value is not true or if the variable is not \ndefined at all for the project, then the HTTP URL will be used by default.\n\n#### gitlab.codeCoverage.variables.generatedCoverageReportFilePathVarName\nThe name of the GitLab variable that specifies the path to the generated coverage report file by the pipeline job.\n\nThis path should be the one that is configured in the pipeline coverage goal step.\n\nExample value of the variable content: target/site/jacoco/jacoco.xml\n\n##### gitlab.mergeRequests.mergeRequestHistoryFolderPath\nThe path to a folder where merge request history fetching statuses should be kept for each of the projects.\n\nIf the folder does not exist, then it will be created automatically.\n\nIn this folder, an empty file for each of the projects will be created (the name of the file will be the id of each \nproject). The meaning of the files is the following: if a file named with an id of a project exists, it means that merge \nrequest history has been fetched for that project.\n\nThe tool consistently listens for changes in the directory and if one file for a specific project is deleted, then it will automatically fetch the merge request history for that project and recreate the file.\n\n## Configuring variables in Gitlab\n\nTo configure variables inside a project you must do the following:\n1. While inside the project click on Settings -\u003e CI/CD\n2. Go to the Variables section and click \"Expand\"\n3. Click on the \"Add Variable\" button\n4. Fill in the \"Key\" and \"Value\" fields and then click the \"Add Variable\" button\n\nThe key of the variable is the name that should be configured in the application.properties file for variable name \nproperties (gitlab.variables.publishMergeRequestVarName, gitlab.variables.destinationWorkspaceVarName,\ngitlab.variables.useSSHFormatVarName).\n\n## Usage instructions\n\n1. Create a new GitLab CI server entity in ALM Octane.\n2. Go to the Pipelines module.\n3. Create a pipeline using the newly created GitLab CI server.\n4. The list only displays pipelines in which the integration user has a MAINTAINER role.\n5. Run the pipeline and wait for the run to finish.\n6. Look at the result – statuses, topology, build entries, and test entries.\n\n## Integration with ALM Octane Test Framework\n\nThe ALM Octane Test Framework allows the running of separate automated tests from ALM Octane using Test Runners.(how to configure [here](docs/TestFramework.md))\n\n## Cleanup webhooks\n\nIt is possible to start the service in clean mode.  \nThis mode allows you to clear all hooks from the GitLab server.\n\nTo clean the webhooks run the following command line:\n\n```  \njava –jar octane-gitlab-service-\u003cversion\u003e.jar --cleanupOnly=true\n```\n## Password encryption\n\nValues of the properties marked as 'sensitive' in the above list can be encrypted before writing them down in the *'application.properties'* file. To encrypt a sensitive token, run the following command line:\n\n```bash\njava –jar octane-gitlab-service-\u003cversion\u003e.jar encrypt \u003csensitive_token\u003e\n``` \n\nThe result should look like this:\n\n```bash\nEncrypted token: AES:oLPF209dEPuL69RUxfG6Wg==:HOsPY6YTUj2OG5aVNtp/xQ==\n```\n\nThe encrypted token that starts with 'AES:' can be directly copied (including the 'AES:' prefix) to the *'application.properties'* file.\nHowever, password encryption is optional. You can enter the password plain values directly.\n## SSL port\n[How to configure the service with SSL port ](https://mkyong.com/spring-boot/spring-boot-ssl-https-examples/)  \n\n## Troubleshooting\n\n### Multi-Branch \n\nAll created pipelines in ALM Octane will be multi-branch pipelines (parent structure of the project which cannot be directly run).\nIn order to inject an actual implementation of a pipeline (e.g. the one defined on the main branch), it needs to be executed from the GitLab side (after the multi-branch structure has been created on the Octane side).\nAfter the execution, the pipeline will be displayed in Octane, as a child of the multi-branch parent.\n\n### Cannot see the project in the job list of Octane\n\nThe project must contain files and not be empty. Make sure there is at least one branch in your GitLab project.\n\n### GitLab WebHooks\n\nIf you can run the pipeline from Octane but cannot see progress and results:  \nCheck the webhook from your project in GitLab (in GitLab go to your `Project`\u003e`Settings`\u003e`Integration` and test the webhooks for your service URL: \u003cservice Url\u003e\\events).\nIf necessary, update the application.properties file with the correct server.baseurl value.\n\n\n### Endpoint not accessible by GitLab\n\nIf you are getting this error:  \n```\nGitlabServices: Error while accessing the '\u003cservice-url\u003e/events' endpoint.  \nNote that this endpoint must be accessible by GitLab.\n```\nIn the service we are running a test for the webhook URL, to see if the endpoint is accessible.\nIf it is not accessible, please check your application.properties file.\nIn case this URL is not accessible from GitLab (for example if GitLab is in a different network),  \nyou can use the “server.webhook.route.url” property to fix your environment.\n \n\n### GitLab Runner HTTP(S) proxy\n\nGitLab uses registered runners for running pipelines. Runners are registered as described in this article: https://docs.gitlab.com/runner/register/.\nIf a runner communicates with the integration service over a network that requires HTTP(S) proxy settings, an easy way to set the proxy is to add it to the runner’s registration entry.\n\nFor example, after registering a runner on a Linux machine, its registration entry resides in the /etc/gitlab-runner/config.toml file. (Tip: If you can’t find this file, run the ‘gitlab-runner list’ shell command – it displays the registration file location as ConfigFile=…). This entry may look as below:\n\n```\n[[runners]]\n  name = \"my-runner\"\n  url = \"http://my-runner.cloudlab.net:30080/\"\n  token = \"4329809ufewjfewkfjnoeihtrjfoif\"\n  executor = \"shell\"\n  builds_dir = \"/workspace\"\n  [runners.cache]\n```\n\nIn order to set the HTTP(S) proxy, an “environment” row should be added to this entry (replace the URL placeholders with the correct values):\n\n```\n[[runners]]\n  name = \"my-runner\"\n  url = \"http://gitlab-placeholder.net:30080/\"\n  token = \"4329809ufewjfewkfjnoeihtrjfoif\"\n  executor = \"shell\"\n  builds_dir = \"/workspace\"\n  environment = [\"HTTPS_PROXY=http://proxy-placeholder.net:8080\", \"HTTP_PROXY=http://proxy-placeholder.net:8080\"]\n  [runners.cache]\n```\n\nAfter adding the proxy settings, restart the gitlab-runner service.\n\n### Logging (Log4J 2 Configuration)\n\nThe project supports Log4J 2 configuration. In application.properties use the property below for specifying the Log4J 2 configuration file.\n```\nlogging.config\n```\n\nFor example:\n```\nlogging.config=./log4j2.xml\n``` \n\nBelow is an example of a Log4J 2 XML configuration:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cConfiguration status=\"warn\"\u003e\n    \u003cProperties\u003e\n        \u003cProperty name=\"basePath\"\u003e./logs\u003c/Property\u003e\n    \u003c/Properties\u003e\n \n    \u003cAppenders\u003e\n        \u003cRollingFile name=\"fileLogger\" fileName=\"${basePath}/app-info.log\" filePattern=\"${basePath}/archive/app-info-%d{yyyy-MM-dd}.log\"\u003e\n            \u003cPatternLayout\u003e\n                \u003cpattern\u003e[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n\u003c/pattern\u003e\n            \u003c/PatternLayout\u003e\n            \u003cPolicies\u003e\n                \u003cTimeBasedTriggeringPolicy interval=\"1\" modulate=\"true\" /\u003e\n            \u003c/Policies\u003e\n        \u003c/RollingFile\u003e \n        \u003cConsole name=\"console\" target=\"SYSTEM_OUT\"\u003e\n            \u003cPatternLayout pattern=\"[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n\" /\u003e\n        \u003c/Console\u003e\n    \u003c/Appenders\u003e\n    \u003cLoggers\u003e\n        \u003cRoot level=\"info\"\u003e\n            \u003cappender-ref ref=\"console\" /\u003e\n            \u003cappender-ref ref=\"fileLogger\" /\u003e\n        \u003c/Root\u003e\n    \u003c/Loggers\u003e\n\u003c/Configuration\u003e\n``` \n\n### Allowing requests to the local network\n\nIf the GitLab server and the octane-gitlab-service app both run on the same network, you need to enable \"Allow requests to the local network from hooks and services\" as follows:\n- Open the [your_gitlab_server]/admin/application_settings page.\n- In the `Outbound requests` section, check the `Allow requests to the local network from hooks and services` checkbox.\n\n### SSL error \n\nIf getting the following error in the log:\n\"javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed:   \nsun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target\"\n- try to install the certificate manually:  \nexample from customer process: \n```\n# add ca cert\ncd /usr/share/your-server/jre/lib/security\n/usr/share/your-server/jre/bin/keytool -import -storepass changeit -noprompt -alias cacert -keystore cacerts -trustcacerts -file /tmp/certificadoOctane.cer\n \n# add octane\\gitlab server cert\ncd /usr/share/your-server/jre/lib/security\n/usr/share/your-server/jre/bin/keytool -import -storepass changeit -noprompt -alias octane-cert -keystore cacerts -trustcacerts -file /tmp/octanecielo.crt\n \n# check if java is using the right ca/cert\ncd /tmp\n[root@ip-172-xxx-xxx-xxx tmp]# wget https://confluence.atlassian.com/download/attachments/225122392/SSLPoke.class?version=1\u0026modificationDate=1288204937304\u0026api=v2\n[root@ip-172-xxx-xxx-xxx tmp]# mv SSLPoke.class\\?version\\=1 SSLPoke.class\n \n[root@ip-172-xxx-xxx-xxx tmp]# java -Djavax.net.ssl.trustStore=/usr/share/your-server/jre/lib/security/cacerts  SSLPoke octanecielo.enterprisetrn.hdevelo.com.br 443\nSuccessfully connected\nProcedure\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrofocus%2Foctane-gitlab-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrofocus%2Foctane-gitlab-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrofocus%2Foctane-gitlab-service/lists"}