Commit 118334c5 authored by Cédric Anne's avatar Cédric Anne
Browse files

Merge branch '9.5/bugfixes'

parents 4c3a0c1e 3aa9ab93
name: "GLPI nightly build"
on:
# Runs test suite every night
schedule:
- cron: '0 0 * * *'
# Enable manual run
workflow_dispatch:
jobs:
build:
......@@ -11,11 +14,12 @@ jobs:
runs-on: "ubuntu-latest"
strategy:
fail-fast: false
max-parallel: 1
matrix:
include:
# build on lower supported version to ensure building tools are compatible with this version
- {branch: "9.4/bugfixes", php-version: "5.6"}
- {branch: "9.5/bugfixes", php-version: "7.2"}
- {branch: "master", php-version: "7.3"}
services:
app:
image: "ghcr.io/glpi-project/githubactions-php:${{ matrix.php-version }}"
......@@ -26,24 +30,69 @@ jobs:
uses: "actions/checkout@v2"
with:
ref: ${{ matrix.branch }}
- name: "Build if updated during the last 24h"
id: updated
run: |
SHA=$( git rev-parse HEAD )
if [ -n "$( git rev-list -n 1 --after="24 hours" $SHA )" ]; then
echo "::set-output name=build::yes"
else
echo "::set-output name=build::no"
fi
- name: "Deploy source into app container"
if: ${{ steps.updated.outputs.build == 'yes' }}
run: |
sudo cp --no-target-directory --preserve --recursive `pwd` /glpi
sudo chown -R 1000:1000 /glpi
- name: "Install dependencies"
if: ${{ steps.updated.outputs.build == 'yes' }}
run: |
docker exec ${{ job.services.app.id }} composer install --optimize-autoloader --prefer-dist --no-interaction --no-progress --no-suggest
- name: "Define release name"
id: release-name
if: ${{ steps.updated.outputs.build == 'yes' }}
run: |
REF_NAME=$(echo ${{ matrix.branch }} | sed -E 's|/|-|')
echo "::set-output name=base::$REF_NAME"
SHA=$(git rev-parse --short HEAD)
echo "release_name=$REF_NAME.$SHA" >> $GITHUB_ENV
- name: "Build"
if: ${{ steps.updated.outputs.build == 'yes' }}
run: |
echo "Y" | docker exec --interactive ${{ job.services.app.id }} tools/make_release.sh . ${{ env.release_name }}
docker cp ${{ job.services.app.id }}:/tmp/glpi-${{ env.release_name }}.tgz ${{ github.workspace }}/${{ env.release_name }}.tar.gz
- name: "Store archive"
uses: actions/upload-artifact@v2
- uses: actions/checkout@v2
if: ${{ steps.updated.outputs.build == 'yes' }}
with:
name: ${{ env.release_name }}.tar.gz
path: ${{ github.workspace }}/${{ env.release_name }}.tar.gz
repository: ${{ github.repository_owner }}/glpi-project.github.io
token: ${{ secrets.GH_PUBLISHING_TOKEN }}
fetch-depth: 0
path: nightly
- name: "Publish nightly"
if: ${{ steps.updated.outputs.build == 'yes' }}
id: publish-nightly
run: |
EMAIL="$(git log --format='%ae' HEAD^!)"
NAME="$(git log --format='%an' HEAD^!)"
chmod +x tools/github-nightly-description.sh
cd nightly
git config --local user.email "$EMAIL"
git config --local user.name "$NAME"
echo "Removing previous ${{ matrix.branch }} builds"
git filter-branch --prune-empty -f --index-filter 'git rm --cached --ignore-unmatch "glpi/${{ steps.release-name.outputs.basename}}.*.tar.gz"' HEAD
cp -vf "${{ github.workspace }}/${{ env.release_name }}.tar.gz" glpi
# script argument should be the ordered list of builds to index
../tools/github-nightly-description.sh `ls -r glpi/*.tar.gz` >glpi/index.md
echo "Repository status:"
git status
ls -lt glpi
# Prepare commit
echo "Adding GLPI ${{ env.release_name }} build"
git add glpi/*
git commit -m "Add GLPI ${{ env.release_name }} nightly build"
# Force commit
git push --force
git status
shell: bash
env:
FILTER_BRANCH_SQUELCH_WARNING: 1
......@@ -1116,14 +1116,6 @@ class CommonDBTM extends CommonGLPI {
}
}
if (isset($input['name'])) {
$input['name'] = strip_tags(Toolbox::unclean_cross_side_scripting_deep($input['name']));
}
if (isset($input['comments'])) {
$input['comments'] = strip_tags(Toolbox::unclean_cross_side_scripting_deep($input['comments']));
}
// Store input in the object to be available in all sub-method / hook
$this->input = $input;
......@@ -1493,14 +1485,6 @@ class CommonDBTM extends CommonGLPI {
return false;
}
if (isset($input['name'])) {
$input['name'] = strip_tags(Toolbox::unclean_cross_side_scripting_deep($input['name']));
}
if (isset($input['comments'])) {
$input['comments'] = strip_tags(Toolbox::unclean_cross_side_scripting_deep($input['comments']));
}
// Store input in the object to be available in all sub-method / hook
$this->input = $input;
......
......@@ -1120,6 +1120,12 @@ final class DbUtils {
} else {
$name = $result['completename'];
}
// Separator is not encoded in DB, and it could not be changed as this is mandatory to be able to split tree
// correctly even if some tree elements are containing ">" char in their name (this one will be encoded).
$separator = ' > ';
$name = implode(Toolbox::clean_cross_side_scripting_deep($separator), explode($separator, $name));
if ($tooltip) {
$comment = sprintf(__('%1$s: %2$s')."<br>",
"<span class='b'>".__('Complete name')."</span>",
......
......@@ -976,20 +976,22 @@ var typewatch = (function(){
* Function that renders select2 selections.
*/
var templateSelection = function (selection) {
var text = '';
if (!("element" in selection)) {
return selection.text;
}
// Data generated by ajax containing 'selection_text'
if (Object.prototype.hasOwnProperty.call(selection, 'selection_text')) {
return selection.selection_text;
}
// Data generated with optgroups
if (selection.element.parentElement.nodeName == 'OPTGROUP') {
return selection.element.parentElement.getAttribute('label') + ' - ' + selection.text;
text = selection.text;
} else if (Object.prototype.hasOwnProperty.call(selection, 'selection_text')) {
// Data generated by ajax containing 'selection_text'
text = selection.selection_text;
} else if (selection.element.parentElement.nodeName == 'OPTGROUP') {
// Data generated with optgroups
text = selection.element.parentElement.getAttribute('label') + ' - ' + selection.text;
} else {
// Default text
text = selection.text;
}
// Default text
return selection.text;
var _elt = $('<span></span>');
_elt.html(escapeMarkupText(text));
return _elt;
};
/**
......
......@@ -122,6 +122,8 @@ class Dropdown extends DbTestCase {
public function testGetDropdownName() {
global $CFG_GLPI;
$encoded_sep = \Toolbox::clean_cross_side_scripting_deep(' > ');
$ret = \Dropdown::getDropdownName('not_a_known_table', 1);
$this->string($ret)->isIdenticalTo('&nbsp;');
......@@ -130,20 +132,20 @@ class Dropdown extends DbTestCase {
$subCat = getItemByTypeName('TaskCategory', '_subcat_1');
// basic test returns string only
$expected = $cat->fields['name']." > ".$subCat->fields['name'];
$expected = $cat->fields['name'].$encoded_sep.$subCat->fields['name'];
$ret = \Dropdown::getDropdownName('glpi_taskcategories', $subCat->getID());
$this->string($ret)->isIdenticalTo($expected);
// test of return with comments
$expected = ['name' => $cat->fields['name']." > ".$subCat->fields['name'],
'comment' => "<span class='b'>Complete name</span>: ".$cat->fields['name']." > "
$expected = ['name' => $cat->fields['name'].$encoded_sep.$subCat->fields['name'],
'comment' => "<span class='b'>Complete name</span>: ".$cat->fields['name'].$encoded_sep
.$subCat->fields['name']."<br><span class='b'>&nbsp;Comments&nbsp;</span>"
.$subCat->fields['comment']];
$ret = \Dropdown::getDropdownName( 'glpi_taskcategories', $subCat->getID(), true );
$this->array($ret)->isIdenticalTo($expected);
// test of return without $tooltip
$expected = ['name' => $cat->fields['name']." > ".$subCat->fields['name'],
$expected = ['name' => $cat->fields['name'].$encoded_sep.$subCat->fields['name'],
'comment' => $subCat->fields['comment']];
$ret = \Dropdown::getDropdownName( 'glpi_taskcategories', $subCat->getID(), true, true, false );
$this->array($ret)->isIdenticalTo($expected);
......@@ -152,7 +154,7 @@ class Dropdown extends DbTestCase {
$CFG_GLPI['translate_dropdowns'] = 1;
$_SESSION["glpilanguage"] = \Session::loadLanguage( 'fr_FR' );
$_SESSION['glpi_dropdowntranslations'] = \DropdownTranslation::getAvailableTranslations($_SESSION["glpilanguage"]);
$expected = ['name' => 'FR - _cat_1 > FR - _subcat_1',
$expected = ['name' => 'FR - _cat_1' . $encoded_sep . 'FR - _subcat_1',
'comment' => 'FR - Commentaire pour sous-catégorie _subcat_1'];
$ret = \Dropdown::getDropdownName( 'glpi_taskcategories', $subCat->getID(), true, true, false );
// switch back to default language
......@@ -793,6 +795,8 @@ class Dropdown extends DbTestCase {
}
protected function getDropdownConnectProvider() {
$encoded_sep = \Toolbox::clean_cross_side_scripting_deep('>');
return [
[
'params' => [
......@@ -806,7 +810,7 @@ class Dropdown extends DbTestCase {
'text' => '-----',
],
1 => [
'text' => 'Root entity > _test_root_entity',
'text' => "Root entity {$encoded_sep} _test_root_entity",
'children' => [
0 => [
'id' => getItemByTypeName('Printer', '_test_printer_all', true),
......@@ -819,7 +823,7 @@ class Dropdown extends DbTestCase {
]
],
2 => [
'text' => 'Root entity > _test_root_entity > _test_child_1',
'text' => "Root entity {$encoded_sep} _test_root_entity {$encoded_sep} _test_child_1",
'children' => [
0 => [
'id' => getItemByTypeName('Printer', '_test_printer_ent1', true),
......@@ -828,7 +832,7 @@ class Dropdown extends DbTestCase {
]
],
3 => [
'text' => 'Root entity > _test_root_entity > _test_child_2',
'text' => "Root entity {$encoded_sep} _test_root_entity {$encoded_sep} _test_child_2",
'children' => [
0 => [
'id' => getItemByTypeName('Printer', '_test_printer_ent2', true),
......@@ -856,7 +860,7 @@ class Dropdown extends DbTestCase {
'text' => '-----',
],
1 => [
'text' => 'Root entity > _test_root_entity',
'text' => "Root entity {$encoded_sep} _test_root_entity",
'children' => [
0 => [
'id' => getItemByTypeName('Printer', '_test_printer_all', true),
......@@ -865,7 +869,7 @@ class Dropdown extends DbTestCase {
]
],
2 => [
'text' => 'Root entity > _test_root_entity > _test_child_1',
'text' => "Root entity {$encoded_sep} _test_root_entity {$encoded_sep} _test_child_1",
'children' => [
0 => [
'id' => getItemByTypeName('Printer', '_test_printer_ent1', true),
......@@ -884,7 +888,7 @@ class Dropdown extends DbTestCase {
'expected' => [
'results' => [
0 => [
'text' => 'Root entity > _test_root_entity',
'text' => "Root entity {$encoded_sep} _test_root_entity",
'children' => [
0 => [
'id' => getItemByTypeName('Printer', '_test_printer_ent0', true),
......@@ -903,7 +907,7 @@ class Dropdown extends DbTestCase {
'expected' => [
'results' => [
0 => [
'text' => 'Root entity > _test_root_entity',
'text' => "Root entity {$encoded_sep} _test_root_entity",
'children' => [
0 => [
'id' => getItemByTypeName('Printer', '_test_printer_ent0', true),
......
......@@ -79,13 +79,14 @@ class NotificationTargetTicket extends DbTestCase {
// advanced test for ##task.categorycomment## and ##task.categoryid## tags
// test of the getDataForObject for default language en_GB
$taskcat = getItemByTypeName('TaskCategory', '_subcat_1');
$encoded_sep = \Toolbox::clean_cross_side_scripting_deep('>');
$expected = [
[
'##task.id##' => 1,
'##task.isprivate##' => 'No',
'##task.author##' => '_test_user',
'##task.categoryid##' => $taskcat->getID(),
'##task.category##' => '_cat_1 > _subcat_1',
'##task.category##' => '_cat_1 ' . $encoded_sep . ' _subcat_1',
'##task.categorycomment##' => 'Comment for sub-category _subcat_1',
'##task.date##' => '2016-10-19 11:50',
'##task.description##' => 'Task to be done',
......@@ -120,7 +121,7 @@ class NotificationTargetTicket extends DbTestCase {
'##task.isprivate##' => 'Non',
'##task.author##' => '_test_user',
'##task.categoryid##' => $taskcat->getID(),
'##task.category##' => 'FR - _cat_1 > FR - _subcat_1',
'##task.category##' => 'FR - _cat_1 ' . $encoded_sep . ' FR - _subcat_1',
'##task.categorycomment##' => 'FR - Commentaire pour sous-catégorie _subcat_1',
'##task.date##' => '2016-10-19 11:50',
'##task.description##' => 'Task to be done',
......
#!/bin/bash -e
#
# ---------------------------------------------------------------------
# GLPI - Gestionnaire Libre de Parc Informatique
# Copyright (C) 2015-2021 Teclib' and contributors.
#
# http://glpi-project.org
#
# based on GLPI - Gestionnaire Libre de Parc Informatique
# Copyright (C) 2003-2014 by the INDEPNET Development Team.
#
# ---------------------------------------------------------------------
#
# LICENSE
#
# This file is part of GLPI.
#
# GLPI is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# GLPI is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GLPI. If not, see <http://www.gnu.org/licenses/>.
# ---------------------------------------------------------------------
#
cat <<HEADER
---
layout: default
title: GLPI Nightly Builds
---
Built on $( date -u +'%F %H:%M:%S UTC' )
HEADER
for file in $*
do
NAME="${file#glpi/}"
BRANCH="${NAME%.*.tar.gz}"
SIZE=$( stat -c %s "$file" )
cat <<DESCRIPTION
## $BRANCH
Archive|Size
---|---
[$NAME]($NAME)|$SIZE
DESCRIPTION
done
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment