immobiliare / backstage-plugin-gitlab Goto Github PK
View Code? Open in Web Editor NEWBackstage plugins to interact with GitLab
License: Apache License 2.0
Backstage plugins to interact with GitLab
License: Apache License 2.0
Hi, the #118 was incomplete and I'd like to add documentation.
Hi People, I'm using this awesome plugin, but recently we have a problem using the filter on the IssueTable. The filter only works for Issue ID and created_at columns. Is intend to work this way or can we make possible to work with author column?
@backstage/plugin-catalog-backend-module-gitlab 0.2.1
Add support for multiple Gitlab instances
If I have CODEOWNERS in the default path, shouldn't I be able to see them? They are not shown. It's worth to specify my codeowners file has only one group and not single individuals
Currently, the groups/${group_slug}
API returns too big data. We have to find a way to reduce the size.
π I'm working on serving backstage behind a reverse proxy, everything seems ok despite this plugin.
Here are all the steps I did :
app-config.yaml
# FRONTEND_BASEURL=http://localhost:7007/instance/backstage
# BACKEND_BASEURL=http://localhost:7007/instance/backstage
# GITLAB_HOST=my-custom-gitlab.com
# GITLAB_TOKEN=my-token
app:
baseUrl: ${FRONTEND_BASEURL}
backend:
baseUrl: ${BACKEND_BASEURL}
integrations:
gitlab:
- host: ${GITLAB_HOST}
token: ${GITLAB_TOKEN}
baseUrl: https://${GITLAB_HOST}
apiBaseUrl: https://${GITLAB_HOST}/api/v4
reverse-proxy.conf
<LocationMatch "^\/instance\/(?<backstage>[^\/]+)(\/?.*)">
ProxyPass "http://$1:7007$2"
ProxyPassReverse "http://$1:7007$2"
</LocationMatch>
# https://localhost/instance/backstage/catalog
# ProxyPass "http://backstage:7007/catalog"
# ProxyPassReverse "http://backstage:7007/catalog"
catalog-info.yaml
metadata:
annotations:
gitlab.com/project-id: '<gitlab-project-id>'
gitlab.com/instance: '<my-custom-gitlab.com>'
Troubleshooting : it's as if the plugin doesn't directly request the gitlab api with the token
backstage.log
# The request goes well up to the backstage instance
GET /api/gitlab/<my-custom-gitlab.com>/projects/<gitlab-project-id>? HTTP/1.1\" 302
Inside backstage container
# docker exec -it backstage bash
curl http://localhost:7007/api/gitlab/<my-custom-gitlab.com>/projects/<gitlab-project-id>
# result
<html><body>You are being <a href="https://<my-custom-gitlab.com>/users/sign_in">redirected</a>.</body></html>
What do you think of removing bots from contributors' cards?
Suggesting feature
Add a ReleasesCard widget that can be put in the Backstage catalog overview
Our organization wants a widget to render the README.md of a GitLab Project.
Would you accept a PR for this new widget? Could be totally optional or added to the default GitLab Page.
It would be helpful if this plugin had a widget that allows a developer to run a build pipeline.
Thoughts?
We have all our code in a monorepo. We have a component in backstage for each app in our monorepo. We tag releases with the name of the app that's being released. Is there any way to set a filter to only show what's relevant for that specific app/tag. CI/CD, Releases etc.
Hi,
I just updated the plugin to 4.0.1, and now using the following setup:
Unfortunately I'm getting the following error now:
Error: useLocation() may be used only in the context of a <Router> component.
at l (webpack-internal:///../../node_modules/@loblaw/backstage-plugin-gitlab/node_modules/react-router-dom/node_modules/react-router/index.js:30:286)
at H (webpack-internal:///../../node_modules/@loblaw/backstage-plugin-gitlab/node_modules/react-router-dom/node_modules/react-router/index.js:39:299)
at G (webpack-internal:///../../node_modules/@loblaw/backstage-plugin-gitlab/node_modules/react-router-dom/node_modules/react-router/index.js:43:33)
at E (webpack-internal:///../../node_modules/@loblaw/backstage-plugin-gitlab/node_modules/react-router-dom/node_modules/react-router/index.js:38:870)
at renderWithHooks (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:14985:18)
at mountIndeterminateComponent (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:17811:13)
at beginWork (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:19049:16)
at HTMLUnknownElement.callCallback (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:3945:14)
at Object.invokeGuardedCallbackDev (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:3994:16)
at invokeGuardedCallback (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:4056:31)
Already tried to completely remove & readd the plugin, to ensure I have everything set up as described in the README
i am getting a version issue when i try to install the plugin, it always shows some react dependency issue , can some one help installling the plugin
Hi people, this is an enhancement we think is valid one. As in author column at IssueTable, is it possible to make a link to creator's profile at Gitlab on Merge Request table?
Sometimes the duration of pipelines evaluated does not coincide with the proper pipeline duration because the pipeline duration is evaluated with the: created_at
and updated_at
API values.
The GitLab API has the pipeline value duration, but to get it, we have to get all information for each pipeline. This requires n
(where n is the length of the list) calls to the API.
we have self hosted gitlab and I setup the integration like so:
integrations:
gitlab:
- host: gitlab.xxxxx.de
token: MY-TOKEN
apiBaseUrl: https://gitlab.xxxxx.de/api/v4
baseUrl: http://gitlab.xxxxx.de
The basic backstage installation cann work with this and can read catalog files from my gitlab repositories.
But the gitlab plugin gives me all kind of 404, when I try to open the gitlab tab of an entity:
... 1] 2023-06-06T08:27:11.419Z backstage info ::ffff:127.0.0.1 - - [06/Jun/2023:08:27:11 +0000] "GET /api/gitlab/gitlab.com/projects/1415/languages? HTTP/1.1" 404 35 "http://localhost:3000/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0" type=incomingRequest [1] 2023-06-06T08:27:11.445Z backstage info ::ffff:127.0.0.1 - - [06/Jun/2023:08:27:11 +0000] "GET /api/gitlab/gitlab.com/projects/1415/merge_requests? HTTP/1.1" 404 35 "http://localhost:3000/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0" type=incomingRequest [1] 2023-06-06T08:27:11.468Z backstage info ::ffff:127.0.0.1 - - [06/Jun/2023:08:27:11 +0000] "GET /api/gitlab/gitlab.com/projects/1415? HTTP/1.1" 404 35 "http://localhost:3000/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0" type=incomingRequest [1] 2023-06-06T08:27:11.668Z backstage info ::ffff:127.0.0.1 - - [06/Jun/2023:08:27:11 +0000] "GET /api/gitlab/gitlab.com/projects/1415? HTTP/1.1" 404 35 "http://localhost:3000/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0" type=incomingRequest [1] 2023-06-06T08:27:11.674Z backstage info ::ffff:127.0.0.1 - - [06/Jun/2023:08:27:11 +0000] "GET /api/gitlab/gitlab.com/projects/1415/repository/contributors?sort=desc HTTP/1.1" 404 35 "http://localhost:3000/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0" type=incomingRequest [1] 2023-06-06T08:27:11.679Z backstage info ::ffff:127.0.0.1 - - [06/Jun/2023:08:27:11 +0000] "GET /api/gitlab/gitlab.com/projects/1415? HTTP/1.1" 404 35 "http://localhost:3000/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0" type=incomingRequest [ ...
did I miss something or is the plugin not working with self hosted gitlab installations?
I have been looking through the documentation to try and utilize my self hosted GitLab instance for org data but after implementing everything in the documentation underneath these pages it does not work. After digging around a bit I found that there is the GitlabOrgDiscoveryEntityProvider
provider definition which is not documented anywhere for usage that I could find. I imagine this plus the scaffolding code is what is needed to make this work. It would be appreciated to get a direction on how to make this work and also add the documentation to the org ingestion page.
After integration, when tried to load Gitlab entity, it fails as shown in screenshot.
Upon checking in browser console network tab, could see URL as
http://{BACKEND_FQDN}:7007/api/gitlab/rest/{ENTERPRISE_GITLAB_DNS}/projects/{GROUP_PATH_AND_PROJECT_PATH_URL_ENCODED}
Above URL resulting in 404 error.
Ideally, it should either be without projects or with "/api/v4"
http://{BACKEND_FQDN}:7007/api/gitlab/rest/{ENTERPRISE_GITLAB_DNS}/{GROUP_PATH_AND_PROJECT_PATH_URL_ENCODED}
or
http://{BACKEND_FQDN}:7007/api/gitlab/rest/{ENTERPRISE_GITLAB_DNS}/api/v4/projects/{GROUP_PATH_AND_PROJECT_PATH_URL_ENCODED}
Have set gitlab integrations properly in app-config.yaml as below
gitlab:
- host: {ENTERPRISE_GITLAB_DNS}
token: XYZ
apiBaseUrl: https://{ENTERPRISE_GITLAB_DNS}/api/v4/
Tried adding annotations as well in component section yaml file as below.
annotations:
gitlab.com/project-slug: {GROUP}/{PROJECT_NAME}
gitlab.com/project-id: '12345' (sample value)
Hi team!
This is more of a suggestion than an issue, and it has to do with the following:
If the plugin does not detect any releases, i.e. if the response length is 0, then it renders an empty fragment; my suggestion is that we rather render the info card but change it so that the only text it shows is "No releases have been made" or similar. Maybe the implementation could look like this:
if (releases.length === 0) {
return (
<InfoCard
title="Releases"
deepLink={{
link: `${project_web_url}/-/releases`,
title: 'go to Releases',
onClick: (e) => {
e.preventDefault();
window.open(`${project_web_url}/-/releases`);
},
}}
variant={props.variant}
className={classes.infoCard}
>
<Typography variant="body2">
No releases have been made
</Typography>
</InfoCard>
);
}
After following the integration steps, including GitlabFillerProcessor, I can see 404 errors in the network tab where the gitlab components are trying to reach an endpoint in the backend.
β http://localhost:7007/api/gitlab/rest/0/projects/{ORGANIZATION}%2F{GROUP}%2F{SUBGROUP}%2F{SUBGROUP}%2F{REPOSITORY}?
I notice that when I make a call without "rest" in the endpoint, I get a valid response with correct data.
β
http://localhost:7007/api/gitlab/0/projects/{ORGANIZATION}%2F{GROUP}%2F{SUBGROUP}%2F{SUBGROUP}%2F{REPOSITORY}?
I'm running into this issue after upgrading backstage from v1.16.0 -> v1.23.0 - but I removed the gitlab plugin before upgrading and am now struggling to add it back. I have read your migration guide, but I was never on v2 in the first place.
My gitlab config is basic:
integrations:
gitlab:
- host: gitlab.com
token: ${GITLAB_TOKEN}
apiBaseUrl: https://gitlab.com/api/v4/
Component
kind, but I have tried adding allowedKinds: ['Component']
explicitly.We upgraded to the backstage version 1.20.0 and since then facing this error in our Windows machines.
Tried to run the same with node v18.18.2 and v18.19.0 as well but same result.
Any suggestion on how to fix this would be helpful.
Error: EMFILE: too many open files, open 'C:\myworkspace\node_modules\@immobiliarelabs\backstage-plugin-gitlab-backend\node_modules\@backstage\backend-app-api\node_modules\@kubernetes\client-node\dist\gen\model\v1beta2FlowSchema.js'
at Object.openSync (node:fs:603:3)
at Object.readFileSync (node:fs:471:35)
at Object.j (C:\workspace\node_modules\tsx\dist\cjs\index.cjs:1:998)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Module.require (node:internal/modules/cjs/loader:1143:19)
at Module.Hook._require.Module.require (c:\workspace\node_modules\require-in-the-middle\index.js:188:39)
at require (node:internal/modules/cjs/helpers:119:18)
at <anonymous> (c:\workspace\node_modules\@immobiliarelabs\backstage-plugin-gitlab-backend\node_modules\@backstage\backend-app-api\node_modules\@kubernetes\client-node\dist\gen\model\models.js:471:22)
at Object.<anonymous> (c:\workspace\node_modules\@immobiliarelabs\backstage-plugin-gitlab-backend\node_modules\@backstage\backend-app-api\node_modules\@kubernetes\client-node\dist\gen\model\models.js:1809:20)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Object.j (C:\workspace\node_modules\tsx\dist\cjs\index.cjs:1:1197)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Module.require (node:internal/modules/cjs/loader:1143:19)
at Module.Hook._require.Module.require (c:\workspace\node_modules\require-in-the-middle\index.js:188:39) {
errno: -4066,
syscall: 'open',
code: 'EMFILE',
The GitLab groups don't have an avatar when groups are private. This is an API auth issue because only the user images do not require auth in gitlab.
Currently, we always call the getProjectDetails
to get the project_id
if the project_id
is not defined using the project_slug.
But the GitLab API allows using the project_slug
as project_id
for calling API, and if we use this approach, we can remove an API call for each component.
Current configuration of the plugin requires a token with scope read_api to access all resources. However by using /gitlab-ci proxy any user logged into backstage can use gitlab apis. e.g.:
https://my.backstage.com/api/proxy/gitlabci/projects
The user is able to list all projects with the token permissions.
Isn't it too permissive?
Is there a way to restrict the calls only to server side?
Hi, when starting up Backstage using the new backend system, I am getting the following error:
TypeError: r.extensionPoints is not iterable
which originates from the following module:
https://github.com/backstage/backstage/blob/master/packages/backend-app-api/src/wiring/BackendInitializer.ts#L187
This is how I am using the plugin:
import {
gitlabPlugin,
catalogPluginGitlabFillerProcessorModule,
} from '@immobiliarelabs/backstage-plugin-gitlab-backend';
...
backend.add(gitlabPlugin);
backend.add(catalogPluginGitlabFillerProcessorModule);
...
Without the GitLab plugin, Backstage is able to start up normally with other plugins.
Would appreciate any hint on this issue, thank you.
Environment:
Backstage - https://github.com/backstage/backstage/releases/tag/v1.21.0
GitLab - https://github.com/immobiliare/backstage-plugin-gitlab/releases/tag/v6.4.0
We can add request caching with a lower TTL to reduce the number of duplicated requests.
This should also be done by caching the stale responses.
Using the plugin in an environment with a baseUrl seems not to work. I tried to deploy the plugin to a backstage installation with for example this baseUrl: https://mykuberneteshost.de/subpath/backstage/... using a selfhosted gitlab installation with this url: https://mygitlabinstallation.de/
On startup the plugin creates a Proxy rewrite rule with this log message: Proxy rewrite rule created "^/subpath/backstage/api/gitlab/mygitlabinstallation.de/" ->"/api/v4"
But this Proxy rewrite rule seems to be wrong. When I try to open https://mykuberneteshost.de/subpath/backstage/api/gitlab/mygitlabinstallation.de/projects/my-group%2Fmyproject the redirect tries to open https://mygitlabinstallation.de/... instead of https://mygitlabinstallation.de/api/v4/...
I found a solution that worked for me, but I'm not sure if it is correct in any case. I copied the source code an rewrote the file https://github.com/immobiliare/backstage-plugin-gitlab/blob/main/packages/gitlab-backend/src/service/router.ts.
There I removed the ${basePath} from the pathRewrite. Line 61 and 63:
pathRewrite: {
[^/api/gitlab/${host}
]: apiUrl.pathname,
},
instead of:
pathRewrite: {
[^${basePath}/api/gitlab/${host}
]: apiUrl.pathname,
},
Running Backstage v1.12.0 and v5.0.0 of the plugin.
When loading the tab associated with the plugin's content, the following error is thrown:
node:_http_outgoing:771
[1] throw new ERR_HTTP_HEADERS_SENT('remove');
[1] ^
[1]
[1] Error [ERR_HTTP_HEADERS_SENT]: Cannot remove headers after they are sent to the client
[1] at new NodeError (node:internal/errors:400:5)
[1] at ClientRequest.removeHeader (node:_http_outgoing:771:11)
[1] at ProxyServer.onProxyReq (C:\dev\van-1-12-0\node_modules\@immobiliarelabs\backstage-plugin-gitlab-backend\dist\index.cjs.js:36:20)
[1] at ProxyServer.emit (C:\dev\van-1-12-0\node_modules\eventemitter3\index.js:184:35)
[1] at ClientRequest.<anonymous> (C:\dev\van-1-12-0\node_modules\http-proxy\lib\http-proxy\passes\web-incoming.js:133:16)
[1] at ClientRequest.emit (node:events:513:28)
[1] at ClientRequest.emit (node:domain:489:12)
[1] at tickOnSocket (node:_http_client:834:7)
[1] at onSocketNT (node:_http_client:897:5)
[1] at process.processTicksAndRejections (node:internal/process/task_queues:83:21) {
[1] code: 'ERR_HTTP_HEADERS_SENT'
[1] }
[1]
[1] Node.js v18.13.0
I have been able to mitigate the error by commenting out the following code:
//@immobilarielabs/backstage-plugin-gitlab-backend/dist/index.cjs/js (L35-37)
onProxyReq: (proxyReq) => {
proxyReq.removeHeader("Authorization");
}
I assume the code is necessary, so I don't view that as likely a long term fix.
Hi, I am new to backstage, and trying to use this gitlab plugin. However, I encounter this issues. Please help. Thank you in advance.
Issues:
Expected Result:
Config:
# app-config.yaml -> I supply those environment variables before run `yarn dev`
integrations:
gitlab:
- host: gitlab.com
token: ${GITLAB_TOKEN}
proxy:
'/gitlabci':
target: '${GITLAB_URL}/api/v4'
allowedMethods: [ 'GET' ]
headers:
PRIVATE-TOKEN: '${GITLAB_TOKEN}'
# example/entities.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: test-backstage
annotations:
gitlab.com/project-id: '39781451'
spec:
type: service
owner: user:guest
lifecycle: production
# packages/app/src/components/catalog/Gitlab.tsx
export const gitlabEntityPage = (
<EntityLayout.Route if={isGitlabAvailable} path="/gitlab" title="Gitlab">
<EntityGitlabContent />
</EntityLayout.Route>
)
# packages/app/src/components/catalog/EntityPage.tsx
const serviceEntityPage = (
<EntityLayout>
...
{gitlabEntityPage}
</EntityLayout>
);
No request to gitlab api After Visit the Entity, When I use gitlab.com/project-slug
with wrong values, there are some GET Request log. I expected It works the same with correct values.
Thank you
Hi,
currently the plugin uses the integration token to access GitLab. Would it be possible to implement another login mechanism, such as OIDC? This would ensure that GitLab access is restricted to the logged-in user rather than a technical user account.
thanks for the awesome plugin!
Hi,
I was wondering if there was a way to use the signed in users GitLab authentication to render the GitLab cards to limit what can be viewed and not leak commits or other information that the user wouldn't have visibility in GitLab.
Thanks
I am kicking the tires using a local backstage build. I am trying to get a gitlab integration working but I am unable to register an existing component. Can someone give me some tips for debugging this? I am using
"@immobiliarelabs/backstage-plugin-gitlab": "^2.1.0"
{"error":{"name":"InputError","message":"Error: Unable to read url, Error: Could not get GitLab project ID for: https://gitlab.com/...../blob/main/catalog-info.yaml, Error: GitLab Error 'undefined', undefined","stack":"InputError: Error: Unable to read url, Error: Could not get GitLab project ID for:
appreciate any insights / tips
I noticed that on the issues and merge request tables, the ID column appears to be the global ID instead of the project-specific one shown to end users ie. what appears in the UI. Since this is a column in a table that users may refer to, it seems more sensible to use the latter (which I think the GItlab API refer to as iid
)
Adding backstage-plugin-gitlab causes entity postprocessing to start failing for the gitlab provider with the following error:
backstage-new-backstage-1 | {"entity":"group:default/dev1","level":"warn","location":"url:git.panka.in/teams/dev1","message":"Processor GitlabFillerProcessor threw an error while postprocessing; caused by TypeError [ERR_INVALID_URL]: Invalid URL","plugin":"catalog","service":"backstage","type":"plugin"}
backstage-new-backstage-1 | {"entity":"group:default/gitlab-instance-97cc0186","level":"warn","location":"url:git.panka.in/teams/gitlab-instance-97cc0186","message":"Processor GitlabFillerProcessor threw an error while postprocessing; caused by TypeError [ERR_INVALID_URL]: Invalid URL","plugin":"catalog","service":"backstage","type":"plugin"}
backstage-new-backstage-1 | {"entity":"user:default/root","level":"warn","location":"url:git.panka.in/root","message":"Processor GitlabFillerProcessor threw an error while postprocessing; caused by TypeError [ERR_INVALID_URL]: Invalid URL","plugin":"catalog","service":"backstage","type":"plugin"}
backstage-new-backstage-1 | {"entity":"user:default/user1","level":"warn","location":"url:git.panka.in/user1","message":"Processor GitlabFillerProcessor threw an error while postprocessing; caused by TypeError [ERR_INVALID_URL]: Invalid URL","plugin":"catalog","service":"backstage","type":"plugin"}
The baseUrl and host entries are set correctly:
integrations:
gitlab:
- host: git.panka.in
token: ${GITLAB_TOKEN}
apiBaseUrl: https://git.panka.in/api/v4
baseUrl: https://git.panka.in
Anything I am missing in my configuration here?
Hello,
I've noticed the multiple GitLab instance support numbers instances as they appear in the GitLab integration config.
AFAIK, the processor runs on catalog entries once they are ingested, so when the GitLab integration array changes (e.g. a new GitLab instance is added), there would be a mismatch on catalog entries that were processed before the change.
I'm suggesting to identify the GitLab instance by a unique ID. I used to maintain an implementation based on the loblaw version that was using the GitLab instance's hostname (GitLab config host
field). Btw, thanks for taking over and actively driving the development of this plugin.
I'm implementing my suggested change for our internal use and would happily contribute upstream.
wdyt?
It would be great if this plugin could collaborate with the @backstage/plugin-catalog-backend-module-gitlab
to populate the project id in the entity module automatically if the user does not set the id in the yaml file.
We can add a card to handle CODEOWNER standard using gitlab API.
The possible gitlab API can be: api/v4/projects/:id/repository/files/CODEOWNERS?ref=master
For now, if the CODEOWNERS file is missing, we show the card with the code owners section but without owners.
I think in that case, we can remove the "owners" section, WDYT?
I'm experiencing an issue because our self hosted gitlab instance runs under a subpath.
e.g. git.company.com/gitlab
When trying to access git.company.com/gitlab/genc/infrastructure/docker
the GitLab Filler Processor tries to call
git.company.com/projects/gitlab/genc/infrastructure/docker
instead of git.company.com/gitlab/projects/genc/infrastructure/docker
-->
http://localhost:8080/api/gitlab/rest/git.company.com/projects/gitlab%2Fgenc%2Finfrastructure%2Fdocker
Maybe related to: #236
Everything else works fine, just the gitlab filler processor does not.
Can you add config details on to fetch tag from gitlab to show on backstage??
It would be cool to be able to see containers associated with a project. Perhaps the 5 latest, or so? Somewhat inspired by the Harbor plugin for Backstage - metadata if/where available, etc.
Are we have a plan to support i18n in backstage-plugin-gitlab
, since backstage had support @antoniomuso
The Gitlab entity page fails to show anything if Merge Requests are disabled (In Settings -> General -> Visibility, project features, permissions) for the repository being viewed, and just gives the following error:
Cannot read properties of undefined (reading 'length')
And if pipelines are disabled:
Cannot read properties of null (reading 'map')
Obviously you can remove the individual sections from the page but that would remove them for all. Would be better if those sections were rendered with a message or nothing at all if the features are disabled.
Adding an environments card would be useful to illustrate the environments that are being used by the project. It used a similar method as other parts of the API.
GitLab API Reference:
https://docs.gitlab.com/ee/api/environments.html
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.