Chez AXOPEN, nous souhaitions se brancher sur GitLabGitLab, c’est une plateforme permettant d’héberger et de gérer des projets web de A à Z. pour récupérer la liste des issues pour un certain projet. On s’est donc lancé dans la création d’un connector Gitlab pour Google Data Studio.
Google Data Studio est un super outil de reporting de plus en plus utilisé qui possède de nombreux atouts. En particulier, il permet de créer des plugins / connectors pour se connecter à différentes sources de données.
En interne, nous souhaitions se brancher sur GitLabGitLab, c’est une plateforme permettant d’héberger et de gérer des projets web de A à Z. pour récupérer la liste des issues pour un certain projet. On s’est donc lancé dans la création d’un connector Gitlab pour Google Data Studio.
Bon on va pas se mentir la documentation de Google est plutôt faible et peu détaillée. Donc on a pas mal miséré pour trouver des exemples fiables. Mais on y est quand même arrivé et avons réussi à faire ce petit script qui permet de récupérer les issues d’un projet choisi au démarrage.
C’est pas hyper propre, surtout au niveau de la gestion des types de données mais ça marche et c’est déjà pas mal. Et concernant notre besoin c’était largement suffisant. Pour l’utiliser, il suffit de remplir l’APIUne API est un programme permettant à deux applications distinctes de communiquer entre elles et d’échanger des données. KEY (générée depuis l’interface de GitLab) et de modifier les url des endpoints.
En espérant que ça puisse aider des personnes qui ont le même besoin. On pourrait le publier en open source mais nous avons trop de souci avec la documentation pour en faire quelque chose de présentable !
{{< highlight javascript "linenos=table">}}
var API\_KEY = " API\_KEY ";
function isAdminUser(){
return true;
}
function getConfig(request) {
var url = [
’https://git.axopen.com/api/v4/projects?private_token=’,
API_KEY];
var response = JSON.parse(UrlFetchApp.fetch(url.join( ")));
var projects = [];
response.forEach(function(value) {
console.log(value.id);
projects.push({
" label ": value.path\_with\_namespace.toUpperCase(),
" value ": ’AB’+value.id
});
});
var config = {
configParams: [
{
" type ": " SELECT_SINGLE ",
" name ": " SELECT_SINGLE ",
" displayName ": " Select one project ",
" helpText ": " Pick only one project ",
" options ": projects
}
]
};
return config;
};
var fontDataSchema = [
{
name: ’id_issue’,
label: ’Issue ID’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’title’,
label: ’Issue title’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’created_at’,
label: ’Created at’,
dataType: ’STRING’
},
{
name: ’updated_at’,
label: ’Updated at’,
dataType: ’STRING’
},
{
name: ’closed_at’,
label: ’Closed at’,
dataType: ’STRING’
},
{
name: ’state’,
label: ’State’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’user\_notes\_count’,
label: ’User notes count’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’description’,
label: ’Description’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’time_estimate’,
label: ’Time estimate’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’total\_time\_spent’,
label: ’Total time spent’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’downvotes’,
label: ’Downvotes’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’upvotes’,
label: ’Upvotes’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’due_date’,
label: ’Due date’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
];
function getSchema(request) {
return {schema: fontDataSchema};
};
function getData(request) {
var dataSchema = [];
request.fields.forEach(function(field) {
for (var i = 0; i < fontDataSchema.length; i++) {
if (fontDataSchema[i].name === field.name) {
dataSchema.push(fontDataSchema[i]);
break;
}
}
});
var url = [
’https://git.axopen.com/api/v4/projects/’+request.configParams.SELECT\_SINGLE.substring(2)+’/issues?private\_token=’,
API_KEY];
var response = JSON.parse(UrlFetchApp.fetch(url.join( ")));
var data = [];
response.forEach(function(value) {
var values = [];
dataSchema.forEach(function(field) {
switch(field.name) {
case ’id_issue’:
values.push(value.id);
break;
case ’title’:
values.push(value.title);
break;
case ’created_at’:
values.push(value.created_at.substring(0,10));
break;
case ’updated_at’:
values.push(value.updated\_at.created\_at.substring(0,10));
break;
case ’closed_at’:
values.push(value.closed\_at.created\_at.substring(0,10));
break;
case ’state’:
values.push(value.state);
break;
case ’upvotes’:
values.push(value.upvotes);
break;
case ’downvotes’:
values.push(value.downvotes);
break;
case ’due_date’:
values.push(value.due\_date.created\_at.substring(0,10));
break;
case ’time_estimate’:
values.push(value.time_estimate);
break;
case ’total\_time\_spent’:
values.push(value.total\_time\_spent);
break;
case ’user\_notes\_count’:
values.push(value.user\_notes\_count);
break;
case ’description’:
values.push(value.description);
break;
default:
values.push( ");
}
});
data.push({
values: values
});
});
return {
schema: dataSchema,
rows: data
};
};
function getAuthType() {
var response = {
" type ": " NONE "
};
return response;
}
{{< / highlight >}}
Réaliser des tests de performances sur une application n’est jamais simple. Il est en effet assez complexe de simuler une montée en charge réaliste, ainsi qu’une activité utilisateur cohérente. Nous allons explorer quelques pistes pour y parvenir
Vous démarrez un projet d’application et voulez mettre en place un outil d’intégration continue pour votre projet ? On vous partage nos conseils et notre retour d’expérience sur le sujet !
Cluster d’un Jboss EAP 6.2 (à partir de 7.x), les nodes du cluster ne se trouvent pas. Erreur du type: "dropping unicast message to wrong destination" ou "null: no physical address for"