Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
Lio Novelli | cfc623ba72 | |
Lio Novelli | 05d3324f10 | |
Lio Novelli | 2e3f6b4bd8 |
14
README.org
14
README.org
|
@ -9,10 +9,16 @@
|
|||
|
||||
This command would send an invoice for last month created from the template
|
||||
file and last month report from youtrack as an email attachment.
|
||||
|
||||
~./rprt.php report -r~
|
||||
|
||||
Asks which report to print from the list of your reports and then prints out
|
||||
a table with that report.
|
||||
|
||||
** Install/Getting started
|
||||
|
||||
Get ~.phar~ file, run configuration wizzard (planned for version 1.0).
|
||||
Get ~.phar~ file from r, run configuration wizzard (planned for version 1.0).
|
||||
|
||||
|
||||
Before version 1.0 is released you have to navigate into ~/app~ directory
|
||||
and call command through ~.rprt.php~ file.
|
||||
|
@ -25,6 +31,12 @@
|
|||
3. You have to allow [[https://support.google.com/accounts/answer/6010255?hl=en][less secure applications]] in your gmail if you are using
|
||||
that email provider.
|
||||
|
||||
*** Building a phar
|
||||
|
||||
php box: https://github.com/box-project/box
|
||||
|
||||
~./box.phar compile~
|
||||
|
||||
** Specs
|
||||
A simple Console Command that prints out monthly report from youtrack.
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,7 @@
|
|||
|
||||
use function DI\create;
|
||||
use function DI\get;
|
||||
use function DI\factory;
|
||||
|
||||
use RprtCli\Commands\InvoiceCommand;
|
||||
use RprtCli\Commands\ReportCommand;
|
||||
|
@ -18,6 +19,7 @@ use RprtCli\Utils\PdfExport\PdfExportInterface;
|
|||
use RprtCli\Utils\PdfExport\PdfExportService;
|
||||
use RprtCli\Utils\TimeTrackingServices\YoutrackInterface;
|
||||
use RprtCli\Utils\TimeTrackingServices\YoutrackService;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
# use Symfony\Component\Translation\Translator;
|
||||
#use Symfony\Component\Translation\Loader\PoFileLoader;
|
||||
|
@ -32,7 +34,13 @@ return [
|
|||
'config.path' => '~/.config/rprt-cli/',
|
||||
'default_locale' => 'en',
|
||||
'guzzle' => get(Client::class),
|
||||
'mpdf' => get(Mpdf::class),
|
||||
// 'mpdf' => get(Mpdf::class),
|
||||
'mpdf' => factory(function (ContainerInterface $c) {
|
||||
return new Mpdf(['tempDir' => sys_get_temp_dir()]);
|
||||
}),
|
||||
// 'mpdf' => function () {
|
||||
// return new Mpdf(['tempDir' => sys_get_temp_dir()]);
|
||||
// },
|
||||
ConfigurationInterface::class => get(ConfigurationService::class),
|
||||
ConfigurationService::class => create()->constructor(
|
||||
get('config.path'),
|
||||
|
|
|
@ -12,7 +12,7 @@ $builder = new ContainerBuilder();
|
|||
$builder->addDefinitions(__DIR__ . '/dependencies.php');
|
||||
$container = $builder->build();
|
||||
|
||||
$application = new Application();
|
||||
$application = new Application('Command Line Tool to process Youtrack Reports', '0.1.0');
|
||||
|
||||
$invoiceCommand = $container->get(InvoiceCommand::class);
|
||||
$application->add($invoiceCommand);
|
||||
|
|
|
@ -201,7 +201,7 @@ class InvoiceCommand extends Command
|
|||
}
|
||||
$output_path = $this->pdfExport->fromDefaultDataToPdf($nice_data);
|
||||
// Notify the user where the file was generated to.
|
||||
$output->writeln("The file was generated at ${output_path}.");
|
||||
$output->writeln("The file was generated at <info>${output_path}</info>.");
|
||||
}
|
||||
|
||||
// return Command::SUCCESS;
|
||||
|
@ -209,7 +209,7 @@ class InvoiceCommand extends Command
|
|||
if ($input->getOption('send') && $output_path) {
|
||||
// @TODO If no output path print an error.
|
||||
// Send email to configured address.
|
||||
if ($recipients = $input->getOption('send-to')) {
|
||||
if ($recipients = $input->getOption('recipients')) {
|
||||
$this->mailer->setRecipients(explode(',', $recipients));
|
||||
}
|
||||
$this->mailer->sendDefaultMail($output_path);
|
||||
|
|
|
@ -199,7 +199,7 @@ class ReportCsv implements ReportCsvInterface
|
|||
$table[] = ReportCsvInterface::SEPARATOR_MEDIUM;
|
||||
$table[] = [null, $project, null, $project_time / 60];
|
||||
$time_sum += (float) $project_time;
|
||||
$all_projects[] = $project;
|
||||
// $all_projects[] = $project;
|
||||
// Add a sum of time for whole day.
|
||||
$table[] = ReportCsvInterface::SEPARATOR_MEDIUM;
|
||||
$table[] = [null, implode(', ', $all_projects), null, $time_sum/60];
|
||||
|
|
|
@ -88,7 +88,7 @@ class PdfExportService implements PdfExportInterface {
|
|||
}
|
||||
$table .= implode('', $rows);
|
||||
$table .= '</tbody></table>';
|
||||
var_dump($table);
|
||||
// var_dump($table);
|
||||
return $table;
|
||||
}
|
||||
|
||||
|
|
|
@ -115,9 +115,14 @@ class YoutrackService implements YoutrackInterface
|
|||
if ($status == 409) {
|
||||
sleep(3);
|
||||
// @TODO Find a way to break of of loop if necessary!
|
||||
$this->downloadReport($report_id);
|
||||
var_dump("409 response status during download of report {$report_id}. Sleep 3 and try again.");
|
||||
return $this->downloadReport($report_id);
|
||||
}
|
||||
}
|
||||
catch (\Throwable $t) {
|
||||
$status = $t->getMessage();
|
||||
var_dump($status);
|
||||
}
|
||||
throw new \Exception("Unable to download report {$report_id}!");
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"main": "rprt.php",
|
||||
"base-path": "app",
|
||||
"compression": "GZ",
|
||||
"output": "../bin/rprt-gz.phar",
|
||||
"blacklist": ["config", "resources", "tests", "translations"],
|
||||
"directories": ["src", "vendor"],
|
||||
"files": [
|
||||
"dependencies.php"
|
||||
],
|
||||
"finder": [
|
||||
{
|
||||
"name": "*.php",
|
||||
"exclude": ["Tests"],
|
||||
"in": "vendor"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Dependencies:
|
||||
# getopt
|
||||
|
||||
# Track drunomix and kurier dailies.
|
||||
# KUR-181 (everyday 9.30)
|
||||
# DEV-122 (tue-fri 10.00) - TEAM-6
|
||||
# DEV-360 (tracking time) - TEAM-14
|
||||
|
||||
# TO DO:
|
||||
# - Implement track cli (WIP)
|
||||
|
||||
|
||||
track_help () {
|
||||
echo "Tracks dailies and other weekly meetings."
|
||||
echo -e "\t-d|--drunomics-daily :: [TEAM-6] Drunomics daily - Tue-Fri(10.00) - 15m."
|
||||
echo -e "\t-w|--drunomics-weekly :: [TEAM-1] Drunomics weekly - Mon(11.00) - 1h."
|
||||
echo -e "\t-k|--kurier-daily :: [KUR-181] Kurier daily - Mon-Fri(9.30) - 15m."
|
||||
echo -e "\t-o|--devops-weekly :: [DEV-1967] DevOps weekly - Mon(14.30) - 60m."
|
||||
echo -e "\t-u|--drupal-weekly :: [CTB-24] Drupal weekly - Wed(14.00) - 30m."
|
||||
echo -e "\t-l|--ldp-weekly :: [LDP-683] LDP weekly - Tue(11.00) - 30m."
|
||||
echo -e "\t-v|--wv-weekly :: [WV-31] WV weekly - Wed(10.30) - 30m."
|
||||
echo -e "\t-e|--kurier-weekly :: [KUR-181] Kurier weekly - Wed(15.00) - 1h."
|
||||
echo -e "\t-p|--lupus-d-weekly :: [CTB-55] Lupus dcpld weekly- Thu(11.00) - 30m."
|
||||
echo -e "\t-t|--tracking-time :: [TEAM-14] Personal time tracking - 15m."
|
||||
echo -e "\t-s|--date :: Date in timestamp-miliseconds. Defaults to [\$(date +%s)000]"
|
||||
echo -e "\tmissing :: Work type id. (Not supported yet)."
|
||||
}
|
||||
|
||||
track_help_color () {
|
||||
green='\033[0;32m'
|
||||
cyan='\033[0;36m'
|
||||
clr='\033[0m'
|
||||
DAY_OF_WEEK=$(date +%u -d "@$DATE")
|
||||
COLOR_TUE_FRI=$clr
|
||||
COLOR_MON=$clr
|
||||
COLOR_TUE=$clr
|
||||
COLOR_WED=$clr
|
||||
COLOR_THU=$clr
|
||||
COLOR_ALL_DAYS=$green
|
||||
COLOR_PERSONAL=$clr
|
||||
if [ "$DAY_OF_WEEK" == "1" ] ; then
|
||||
COLOR_MON=$green
|
||||
COLOR_MON_2=$cyan
|
||||
elif [ "$DAY_OF_WEEK" == "2" ] ; then
|
||||
COLOR_TUE=$green
|
||||
COLOR_TEAM6=$green
|
||||
COLOR_TUE_FRI=$green
|
||||
elif [ "$DAY_OF_WEEK" == "3" ] ; then
|
||||
COLOR_WED=$green
|
||||
COLOR_TUE_FRI=$green
|
||||
elif [ "$DAY_OF_WEEK" == "4" ] ; then
|
||||
COLOR_THU=$green
|
||||
COLOR_TUE_FRI=$green
|
||||
elif [ "$DAY_OF_WEEK" == "5" ] ; then
|
||||
COLOR_TUE_FRI=$green
|
||||
else
|
||||
COLOR_ALL_DAYS=$clr
|
||||
fi
|
||||
if [ "$DEV360" == "1" ] ; then
|
||||
COLOR_PERSONAL=$green
|
||||
fi
|
||||
echo "Tracks dailies and other weekly meetings."
|
||||
echo -e "\t-w|--drunomics-weekly :: ${COLOR_MON}[TEAM-1]${clr} Drunomics weekly - ${COLOR_MON}Mon(11.00)${clr} - ${DEV46}m."
|
||||
echo -e "\t-o|--devops-weekly :: ${COLOR_MON}[DEV-1967]${clr} DevOps weekly - ${COLOR_MON}Mon(14.00)${clr} - ${DEVOPS}m."
|
||||
echo -e "\t-d|--drunomics-daily :: ${COLOR_TUE_FRI}[TEAM-6]${clr} Drunomics daily - ${COLOR_TUE_FRI}Tue-Fri(10.00)${clr} - ${DEV122}m."
|
||||
echo -e "\t-k|--kurier-daily :: ${COLOR_ALL_DAYS}[KUR-181]${clr} Kurier daily - ${COLOR_ALL_DAYS}Mon-Fri(9.30)${clr} - ${KUR181}m."
|
||||
echo -e "\t-l|--ldp-weekly :: ${COLOR_TUE}[LDP-683]${clr} LDP weekly - ${COLOR_TUE}Tue(11.00)${clr} - ${LDP683}m."
|
||||
echo -e "\t-u|--drupal-weekly :: ${COLOR_WED}[CTB-24]${clr} Drupal weekly - ${COLOR_WED}Wed(14.00)${clr} - ${CTB24}m."
|
||||
echo -e "\t-v|--wv-weekly :: ${COLOR_WED}[WV-31]${clr} WV weekly - ${COLOR_WED}Wed(10.30)${clr} - ${WV31}m."
|
||||
echo -e "\t-e|--kurier-weekly :: ${COLOR_WED}[KUR-182]${clr} Kurier weekly - ${COLOR_WED}Wed(15.00)${clr} - ${KUR182}."
|
||||
echo -e "\t-p|--lupus-d-weekly :: ${COLOR_THU}[CTB-55]${clr} Lupus dcpld weekly- ${COLOR_WED}Thu(11.00)${clr} - ${CTB55}."
|
||||
echo -e "\t-t|--tracking-time :: ${COLOR_PERSONAL}[TEAM-14]${clr} Personal time tracking - 15m."
|
||||
echo -e "\t-s|--date :: Date in timestamp-miliseconds. Defaults to [\$(date +%s)000]"
|
||||
echo -e "\tmissing :: Work type id. (Not supported yet)."
|
||||
}
|
||||
|
||||
DEV122=15 # now TEAM-6
|
||||
DEV46=60 # now TEAM-1
|
||||
KUR181=15
|
||||
KUR182=60
|
||||
WV31=30
|
||||
LDP683=30
|
||||
DEV360=0 # now TEAM-14
|
||||
DEVOPS=60
|
||||
CTB24=30
|
||||
CTB55=30
|
||||
DATE=$(date +%s)
|
||||
|
||||
# options may be followed by one colon to indicate they have a required argument
|
||||
if ! options=$(getopt -u -o thd:w:k:e:l:v:s:o:u:p: -l help,time-tracking,drunomics-daily:,drunomics-weekly:,kurier-daily:,kurier-weekly:,ldp-weekly:,wv-weekly:,devops-weekly,drupal-weekly,lupus-d-weekly,date -- "$@")
|
||||
then
|
||||
# something went wrong, getopt will put out an error message for us
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -- $options
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case $1 in
|
||||
-t|--tracking-time) DEV360=1 ;;
|
||||
-d|--drunomics-daily) DEV122=$2 ; shift ;;
|
||||
-w|--drunomics-weekly) DEV46=$2 ; shift ;;
|
||||
-k|--kurier-daily) KUR181=$2 ; shift ;;
|
||||
-e|--kurier-weekly) KUR182=$2 ; shift ;;
|
||||
-l|--ldp-weekly) LDP683=$2 ; shift ;;
|
||||
-v|--wv-weekly) WV31=$2 ; shift ;;
|
||||
-o|--devops-weekly) DEVOPS=$2 ; shift ;;
|
||||
-u|--drupal-weekly) CTB24=$2 ; shift ;;
|
||||
-p|--lupus-d-weekly) CTB55=$2 ; shift ;;
|
||||
-h|--help) TRACK_HELP=1;;
|
||||
-s|--date) DATE=$2 ; shift ;;
|
||||
(--) shift; break;;
|
||||
(-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
|
||||
(*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
if [ "$TRACK_HELP" == "1" ] ; then
|
||||
track_help_color
|
||||
else
|
||||
DAY_OF_WEEK=$(date +%u -d "@$DATE")
|
||||
if [ "$DAY_OF_WEEK" == "1" ] ; then
|
||||
echo "Monday: Kurier daily, Drunomics weekly, DevOps weekly:"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh KUR-181 $KUR181 'daily' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh TEAM-1 $DEV46 'weekly' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh DEV-1967 $DEVOPS 'weekly' "$(echo $DATE)000"
|
||||
elif [ "$DAY_OF_WEEK" == "2" ] ; then
|
||||
echo "Tuesday: Kurier daily, Drunomics daily, LDP weekly:"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh KUR-181 $KUR181 'daily + retro' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh TEAM-6 $DEV122 'daily' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh LDP-683 $LDP683 'ldp weekly' "$(echo $DATE)000"
|
||||
elif [ "$DAY_OF_WEEK" == "3" ] ; then
|
||||
echo "Wednesday: Kurier daily, Drunomics daily, Wirtschaftsverlag weekly, Kurier weekly:"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh KUR-181 $KUR181 'daily' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh TEAM-6 $DEV122 'daily' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh CTB-24 $CTB24 'drupal weekly' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh KUR-182 $KUR182 'Kurier weekly grooming' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh WV-31 $WV31 'weekly' "$(echo $DATE)000"
|
||||
elif [ $DAY_OF_WEEK == "4" ] ; then
|
||||
echo "Thursday: Kurier, Drunomics daily, Lupus Decoupled weekly:"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh CTB-55 $CTB55 'weekly' "$(echo $DATE)000"
|
||||
elif [ $DAY_OF_WEEK -gt 5 ] ; then
|
||||
echo "No dailies over the weekend."
|
||||
else
|
||||
echo "Youtrack drunomix & kurier dailies"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh KUR-181 $KUR181 'daily' "$(echo $DATE)000"
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh TEAM-6 $DEV122 'daily' "$(echo $DATE)000"
|
||||
fi
|
||||
if [ "$DEV360" == "1" ] ; then
|
||||
/home/lio/Projects/drunomix/ytest/scripts/ytrack.sh TEAM-14 15 'tracking time' "$(echo $DATE)000"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,73 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Usage:
|
||||
# First export your youtrack api token (you can put this in .bashrc)
|
||||
#
|
||||
# export YTOKEN=<your-youtrack-token-created-in-yt-hub>
|
||||
#
|
||||
# All parameters are optional but the sort order defines priority
|
||||
#
|
||||
# ytrack.sh <issue-name> <time> <description> <timestamp-miliseconds>
|
||||
#
|
||||
# or:
|
||||
#
|
||||
# ytrack.sh [DEV-122] [15] [daily] [1631567581342]
|
||||
#
|
||||
# @TODO:
|
||||
# - Figure a nice way to set type: Development(57-0), Project management, Testing & Review(57-1)...
|
||||
# - Write a proper script with parameters and everything
|
||||
|
||||
# Development (57-0)
|
||||
# Testing, Review (57-1)
|
||||
|
||||
track_help () {
|
||||
echo "Youtrack command line tool."
|
||||
echo -e "\t\$1 :: Ticket name. Defaults to [DEV-122]."
|
||||
echo -e "\t\$2 :: Number of minutes. Defaults to [15]."
|
||||
echo -e "\t\$3 :: Work item description. Defaults to [daily]."
|
||||
echo -e "\t\$4 :: Date in timestamp-miliseconds. Defaults to [\$(date +%s)000]"
|
||||
echo -e "\t\$5 :: Work type id. (Not supported yet)."
|
||||
}
|
||||
|
||||
# FLAGS SETUP
|
||||
while getopts "h" option
|
||||
do
|
||||
case "${option}"
|
||||
in
|
||||
h) TRACK_HELP=1;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND -1))
|
||||
|
||||
if [ "$TRACK_HELP" == "1" ] ; then
|
||||
track_help
|
||||
else
|
||||
YT_ISSUE=${1:-DEV-122}
|
||||
YT_MINUTES=${2:-15}
|
||||
YT_TEXT=${3:-daily}
|
||||
CURRENT_DATE="$(date +%s)000"
|
||||
YT_DATE=${4:-$CURRENT_DATE}
|
||||
YT_WORK_TYPE=${5:-null}
|
||||
|
||||
YT_USER_RESP=$(curl -s 'https://drunomics.myjetbrains.com/youtrack/api/admin/users/me?fields=id,mail,fullName' -H "Authorization: Bearer $YTOKEN" -H 'Cache-Control: no-cache')
|
||||
|
||||
YT_USER_ID=$(echo $YT_USER_RESP | jq .id)
|
||||
YT_USER_ID="${YT_USER_ID:1:-1}"
|
||||
YT_USER_NAME=$(echo $YT_USER_RESP | jq .fullName)
|
||||
|
||||
YT_ISSUE_ID=$(curl -s "https://drunomics.myjetbrains.com/youtrack/api/issues?fields=id,idReadable&query=$YT_ISSUE" -H "Authorization: Bearer $YTOKEN" -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -H 'Accept: application/json' | jq -c ".[] | select ( .idReadable == \"$YT_ISSUE\") | .id")
|
||||
YT_ISSUE_ID="${YT_ISSUE_ID:1:-1}"
|
||||
|
||||
echo "issue: $YT_ISSUE"
|
||||
echo "issue_id: $YT_ISSUE_ID"
|
||||
echo "minutes: $YT_MINUTES"
|
||||
echo "text: $YT_TEXT"
|
||||
echo "date: $YT_DATE"
|
||||
echo "user: $YT_USER_NAME"
|
||||
echo "type: $YT_WORK_TYPE"
|
||||
|
||||
# curl -s -X POST "https://drunomics.myjetbrains.com/youtrack/api/issues/$YT_ISSUE_ID/timeTracking/workItems?fields=id,created,type(name,id),author(name,id),duration(minutes,presentation)" -H "Authorization: Bearer $YTOKEN" -H 'Cache-Control: no-cache' -d "{\"author\": {\"id\":\"$YT_USER_ID\"},\"duration\":{\"minutes\":$YT_MINUTES},\"text\":\"$YT_TEXT\",\"date\":$YT_DATE,\"type\":{\"id\":\"$YT_WORK_TYPE\"}}" -H 'Content-Type: application/json' | jq .
|
||||
curl -s -X POST "https://drunomics.myjetbrains.com/youtrack/api/issues/$YT_ISSUE_ID/timeTracking/workItems?fields=id,created,type(name,id),author(name,id),duration(minutes,presentation)" -H "Authorization: Bearer $YTOKEN" -H 'Cache-Control: no-cache' -d "{\"author\": {\"id\":\"$YT_USER_ID\"},\"duration\":{\"minutes\":$YT_MINUTES},\"text\":\"$YT_TEXT\",\"date\":$YT_DATE}" -H 'Content-Type: application/json' | jq .
|
||||
fi
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
TODO:
|
||||
- nice report selection
|
||||
- clean up the config (default reports)
|
||||
- Improve readme
|
||||
- abstract baseCommand with some input params
|
||||
- add time tracking command
|
||||
- plugin system for services:
|
||||
- in dependencies.php find subdependencies.php
|
||||
- Create interface for 3rd party service integration and abstract class
|
||||
- Create factory to add correct service of a 3rd party service to the Command
|
||||
- separator constant
|
||||
------------------------
|
||||
- add plugin system for time tracking service
|
||||
- add tests
|
||||
------------------------
|
||||
- question helper: https://symfony.com/doc/current/components/console/helpers/questionhelper.html
|
||||
- psr-12 code check and add phpstan https://phpstan.org/user-guide/getting-started
|
||||
- phing for build automation
|
||||
- add ddev for dockerization
|
||||
|
||||
|
||||
|
||||
|
||||
DONE:
|
||||
- expenses default value
|
||||
- pretify output
|
||||
- rename rprt to invoice
|
||||
- select report
|
||||
- build phar file
|
||||
- upload a phar file on repo
|
||||
- create release
|
||||
- clear report cache
|
||||
|
Loading…
Reference in New Issue