This is an automated email from the ASF dual-hosted git repository.
jstastnycz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-optaplanner.git
The following commit(s) were added to refs/heads/main by this push:
new 1e55e1b4e1 kie-issues#727: define push GH tokens for jenkins
1e55e1b4e1 is described below
commit 1e55e1b4e1541cc20acbce49ede3d571e435a635
Author: jstastny-cz <[email protected]>
AuthorDate: Tue Nov 28 13:30:09 2023 +0100
kie-issues#727: define push GH tokens for jenkins
---
.ci/jenkins/Jenkinsfile.deploy | 18 ++++++++++------
.ci/jenkins/Jenkinsfile.promote | 32 ++++++++++++++++------------
.ci/jenkins/Jenkinsfile.setup-branch | 14 +++++++-----
.ci/jenkins/config/branch.yaml | 5 +++++
.ci/jenkins/config/main.yaml | 2 ++
.ci/jenkins/dsl/jobs.groovy | 19 ++++++++++-------
.ci/jenkins/project/Jenkinsfile.drools | 10 ++++++---
.ci/jenkins/project/Jenkinsfile.nightly | 8 +++----
.ci/jenkins/project/Jenkinsfile.post-release | 24 ++++++++++++---------
9 files changed, 81 insertions(+), 51 deletions(-)
diff --git a/.ci/jenkins/Jenkinsfile.deploy b/.ci/jenkins/Jenkinsfile.deploy
index d39d18a169..ef2922e592 100644
--- a/.ci/jenkins/Jenkinsfile.deploy
+++ b/.ci/jenkins/Jenkinsfile.deploy
@@ -316,7 +316,7 @@ void checkoutRepo(String repo, String dirName = repo) {
if (params.PR_TARGET_BRANCH) {
githubscm.checkoutIfExists(repo, getGitAuthor(), getBuildBranch(),
'apache', getFallbackBranch(repo), true)
} else {
- checkout(githubscm.resolveRepository(repo, getGitAuthor(),
getBuildBranch(), false))
+ checkout(githubscm.resolveRepository(repo, getGitAuthor(),
getBuildBranch(), false, getGitAuthorCredsId()))
}
}
}
@@ -327,7 +327,7 @@ void checkoutQuickstarts(String dirName =
quickstartsRepository) {
if (params.PR_TARGET_BRANCH) {
githubscm.checkoutIfExists(quickstartsRepository, getGitAuthor(),
getBuildBranch(), 'apache', getQuickStartsBranch(), true)
} else {
- checkout(githubscm.resolveRepository(quickstartsRepository,
getGitAuthor(), getQuickStartsBranch(), false))
+ checkout(githubscm.resolveRepository(quickstartsRepository,
getGitAuthor(), getQuickStartsBranch(), false, getGitAuthorCredsId()))
}
}
}
@@ -358,10 +358,10 @@ void commitAndCreatePR(String folder, String repo, String
buildBranch) {
githubscm.findAndStageNotIgnoredFiles('build.gradle')
githubscm.findAndStageNotIgnoredFiles('antora.yml')
})
- githubscm.pushObject('origin', getPRBranch(), getGitAuthorCredsID())
+ githubscm.pushObject('origin', getPRBranch(),
getGitAuthorPushCredsId())
deployProperties["${repo}.pr.link"] = isRelease() ?
- githubscm.createPRWithLabels(commitMsg, prBody, buildBranch,
['DO_NOT_MERGE'] as String[], getGitAuthorCredsID()) :
- githubscm.createPR(commitMsg, prBody, buildBranch,
getGitAuthorCredsID())
+ githubscm.createPRWithLabels(commitMsg, prBody, buildBranch,
['DO_NOT_MERGE'] as String[], getGitAuthorCredsId()) :
+ githubscm.createPR(commitMsg, prBody, buildBranch,
getGitAuthorCredsId())
}
}
@@ -478,8 +478,12 @@ String getGitAuthor() {
return "${GIT_AUTHOR}"
}
-String getGitAuthorCredsID() {
- return env.AUTHOR_CREDS_ID
+String getGitAuthorCredsId() {
+ return env.GIT_AUTHOR_CREDS_ID
+}
+
+String getGitAuthorPushCredsId() {
+ return env.GIT_AUTHOR_PUSH_CREDS_ID
}
String getBuildBranch() {
diff --git a/.ci/jenkins/Jenkinsfile.promote b/.ci/jenkins/Jenkinsfile.promote
index 50a453a22e..3572b4f35c 100644
--- a/.ci/jenkins/Jenkinsfile.promote
+++ b/.ci/jenkins/Jenkinsfile.promote
@@ -61,11 +61,11 @@ pipeline {
mergeAndPush(getDeployPrLink(optaplannerRepository))
tagLatest()
- if(githubscm.isReleaseExist(getGitTag(),
getGitAuthorCredsID())) {
- githubscm.deleteRelease(getGitTag(),
getGitAuthorCredsID())
+ if(githubscm.isReleaseExist(getGitTag(),
getGitAuthorCredsId())) {
+ githubscm.deleteRelease(getGitTag(),
getGitAuthorCredsId())
}
-
githubscm.createReleaseWithGeneratedReleaseNotes(getGitTag(), getBuildBranch(),
githubscm.getPreviousTagFromVersion(getGitTag()), getGitAuthorCredsID())
- githubscm.updateReleaseBody(getGitTag(),
getGitAuthorCredsID())
+
githubscm.createReleaseWithGeneratedReleaseNotes(getGitTag(), getBuildBranch(),
githubscm.getPreviousTagFromVersion(getGitTag()), getGitAuthorCredsId())
+ githubscm.updateReleaseBody(getGitTag(),
getGitAuthorCredsId())
}
}
}
@@ -79,11 +79,11 @@ pipeline {
mergeAndPush(getDeployPrLink(quickstartsRepository))
tagLatest()
- if(githubscm.isReleaseExist(getGitTag(),
getGitAuthorCredsID())) {
- githubscm.deleteRelease(getGitTag(),
getGitAuthorCredsID())
+ if(githubscm.isReleaseExist(getGitTag(),
getGitAuthorCredsId())) {
+ githubscm.deleteRelease(getGitTag(),
getGitAuthorCredsId())
}
-
githubscm.createReleaseWithGeneratedReleaseNotes(getGitTag(), getBuildBranch(),
githubscm.getPreviousTagFromVersion(getGitTag()), getGitAuthorCredsID())
- githubscm.updateReleaseBody(getGitTag(),
getGitAuthorCredsID())
+
githubscm.createReleaseWithGeneratedReleaseNotes(getGitTag(), getBuildBranch(),
githubscm.getPreviousTagFromVersion(getGitTag()), getGitAuthorCredsId())
+ githubscm.updateReleaseBody(getGitTag(),
getGitAuthorCredsId())
}
}
}
@@ -195,8 +195,12 @@ String getGitAuthor() {
return env.GIT_AUTHOR
}
-String getGitAuthorCredsID() {
- return env.AUTHOR_CREDS_ID
+String getGitAuthorCredsId() {
+ return env.GIT_AUTHOR_CREDS_ID
+}
+
+String getGitAuthorPushCredsId() {
+ return env.GIT_AUTHOR_PUSH_CREDS_ID
}
String getDeployPrLink(String repo) {
@@ -209,15 +213,15 @@ String getDeployPrLink(String repo) {
void checkoutRepo(String repo) {
deleteDir()
- checkout(githubscm.resolveRepository(repo, getGitAuthor(),
getBuildBranch(), false))
+ checkout(githubscm.resolveRepository(repo, getGitAuthor(),
getBuildBranch(), false, getGitAuthorCredsId()))
// need to manually checkout branch since on a detached branch after
checkout command
sh "git checkout ${getBuildBranch()}"
}
void mergeAndPush(String prLink, String targetBranch) {
if (prLink != '') {
- githubscm.mergePR(prLink, getGitAuthorCredsID())
- githubscm.pushObject('origin', targetBranch, getGitAuthorCredsID())
+ githubscm.mergePR(prLink, getGitAuthorCredsId())
+ githubscm.pushObject('origin', targetBranch, getGitAuthorPushCredsId())
}
}
@@ -227,7 +231,7 @@ void mergeAndPush(String prLink) {
void tagLatest() {
if (getGitTag() != '') {
- githubscm.tagLocalAndRemoteRepository('origin', getGitTag(),
getGitAuthorCredsID(), env.BUILD_TAG, true)
+ githubscm.tagLocalAndRemoteRepository('origin', getGitTag(),
getGitAuthorPushCredsId(), env.BUILD_TAG, true)
}
}
diff --git a/.ci/jenkins/Jenkinsfile.setup-branch
b/.ci/jenkins/Jenkinsfile.setup-branch
index ee38758da7..f23de513a8 100644
--- a/.ci/jenkins/Jenkinsfile.setup-branch
+++ b/.ci/jenkins/Jenkinsfile.setup-branch
@@ -63,7 +63,7 @@ pipeline {
githubscm.findAndStageNotIgnoredFiles('pom.xml')
githubscm.findAndStageNotIgnoredFiles('antora.yml')
})
- githubscm.pushObject('origin', getBuildBranch(),
getGitAuthorCredsId())
+ githubscm.pushObject('origin', getBuildBranch(),
getGitAuthorPushCredsId())
} else {
println '[WARN] no changes to commit'
}
@@ -106,7 +106,7 @@ void sendErrorNotification() {
}
void checkoutRepo(String repository, String branch) {
- checkout(githubscm.resolveRepository(repository, getGitAuthor(), branch,
false))
+ checkout(githubscm.resolveRepository(repository, getGitAuthor(), branch,
false, getGitAuthorCredsId()))
// need to manually checkout branch since on a detached branch after
checkout command
sh "git checkout ${branch}"
}
@@ -129,7 +129,11 @@ String getOptaPlannerVersion() {
}
String getGitAuthorCredsId() {
- return env.AUTHOR_CREDS_ID
+ return env.GIT_AUTHOR_CREDS_ID
+}
+
+String getGitAuthorPushCredsId() {
+ return env.GIT_AUTHOR_PUSH_CREDS_ID
}
MavenCommand getMavenCommand() {
@@ -144,14 +148,14 @@ boolean isMainBranch() {
String commitAndCreatePR(String commitMsg, String localBranch, String
targetBranch) {
def prBody = "Generated by build ${BUILD_TAG}: ${BUILD_URL}"
githubscm.commitChanges(commitMsg)
- githubscm.pushObject('origin', localBranch, getGitAuthorCredsId())
+ githubscm.pushObject('origin', localBranch, getGitAuthorPushCredsId())
return githubscm.createPR(commitMsg, prBody, targetBranch,
getGitAuthorCredsId())
}
void mergeAndPush(String prLink, String targetBranch) {
if (prLink?.trim()) {
githubscm.mergePR(prLink, getGitAuthorCredsId())
- githubscm.pushObject('origin', targetBranch, getGitAuthorCredsId())
+ githubscm.pushObject('origin', targetBranch, getGitAuthorPushCredsId())
}
}
diff --git a/.ci/jenkins/config/branch.yaml b/.ci/jenkins/config/branch.yaml
index b2a46e58f8..145f634c96 100644
--- a/.ci/jenkins/config/branch.yaml
+++ b/.ci/jenkins/config/branch.yaml
@@ -39,9 +39,14 @@ git:
# Need to be verified
credentials_id: 399061d0-5ab5-4142-a186-a52081fef742
token_credentials_id: ci-builds
+ push:
+ credentials_id: 84811880-2025-45b6-a44c-2f33bef30ad2 # CI Push Access
for KIE
+ token_credentials_id: 41128c14-bb63-4708-9074-d20a318ee630 # GitHub
Personal Access Token for KIE
fork_author:
name: kie-ci
credentials_id: kie-ci
+ push:
+ credentials_id: kie-ci
quarkus:
author:
name: quarkusio
diff --git a/.ci/jenkins/config/main.yaml b/.ci/jenkins/config/main.yaml
index 4eded94d4b..42b8b5163e 100644
--- a/.ci/jenkins/config/main.yaml
+++ b/.ci/jenkins/config/main.yaml
@@ -20,6 +20,8 @@ seed:
author:
name: apache
credentials_id: ASF_Cloudbees_Jenkins_ci-builds
+ push:
+ credentials_id: 84811880-2025-45b6-a44c-2f33bef30ad2 # CI Push
Access for KIE
branch: main
path: .ci/jenkins/config/branch.yaml
jenkins:
diff --git a/.ci/jenkins/dsl/jobs.groovy b/.ci/jenkins/dsl/jobs.groovy
index 3b45901ab1..04aea49c50 100644
--- a/.ci/jenkins/dsl/jobs.groovy
+++ b/.ci/jenkins/dsl/jobs.groovy
@@ -73,6 +73,8 @@ void setupProjectDroolsJob(String droolsBranch) {
NOTIFICATION_JOB_NAME: 'Drools snapshot check',
DROOLS_BRANCH: droolsBranch,
MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}",
+
+ GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
])
KogitoJobTemplate.createPipelineJob(this, jobParams)?.with {
parameters {
@@ -109,7 +111,7 @@ void setupProjectNightlyJob() {
GIT_BRANCH_NAME: "${GIT_BRANCH}",
GIT_AUTHOR: "${GIT_AUTHOR_NAME}",
- AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
+ GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}",
ARTIFACTS_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}",
@@ -156,8 +158,8 @@ void setupProjectPostReleaseJob() {
GIT_AUTHOR: "${GIT_AUTHOR_NAME}",
- AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
- GITHUB_TOKEN_CREDS_ID: "${GIT_AUTHOR_TOKEN_CREDENTIALS_ID}",
+ GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
+ GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}",
MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}",
MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}",
@@ -257,7 +259,8 @@ void createSetupBranchJob() {
JENKINS_EMAIL_CREDS_ID: "${JENKINS_EMAIL_CREDS_ID}",
GIT_AUTHOR: "${GIT_AUTHOR_NAME}",
- AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
+ GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
+ GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}",
MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}",
@@ -303,8 +306,8 @@ void setupDeployJob(JobType jobType, String envName = '') {
jobParams.env.putAll([
GIT_AUTHOR: "${GIT_AUTHOR_NAME}",
- AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
- GITHUB_TOKEN_CREDS_ID: "${GIT_AUTHOR_TOKEN_CREDENTIALS_ID}",
+ GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
+ GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}",
MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}",
MAVEN_DEPLOY_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}",
@@ -364,8 +367,8 @@ void setupPromoteJob(JobType jobType) {
GIT_AUTHOR: "${GIT_AUTHOR_NAME}",
- AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
- GITHUB_TOKEN_CREDS_ID: "${GIT_AUTHOR_TOKEN_CREDENTIALS_ID}",
+ GIT_AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}",
+ GIT_AUTHOR_PUSH_CREDS_ID: "${GIT_AUTHOR_PUSH_CREDENTIALS_ID}",
MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}",
MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}",
diff --git a/.ci/jenkins/project/Jenkinsfile.drools
b/.ci/jenkins/project/Jenkinsfile.drools
index 6ecc2e3d80..af3fb68c44 100644
--- a/.ci/jenkins/project/Jenkinsfile.drools
+++ b/.ci/jenkins/project/Jenkinsfile.drools
@@ -133,7 +133,7 @@ void sendErrorNotification() {
void checkoutOptaplannerRepo() {
dir(optaplannerRepo) {
- checkout(githubscm.resolveRepository(optaplannerRepo,
params.GIT_AUTHOR, getBuildBranch(), false))
+ checkout(githubscm.resolveRepository(optaplannerRepo,
params.GIT_AUTHOR, getBuildBranch(), false, getGitAuthorCredsId()))
}
}
@@ -143,13 +143,13 @@ void checkoutOptaplannerQuickstartsRepo() {
? 'development' : getBuildBranch()
dir(quickstartsRepo) {
- checkout(githubscm.resolveRepository(quickstartsRepo,
params.GIT_AUTHOR, quickstartsChangeTarget, false))
+ checkout(githubscm.resolveRepository(quickstartsRepo,
params.GIT_AUTHOR, quickstartsChangeTarget, false, getGitAuthorCredsId()))
}
}
void checkoutDroolsRepo() {
dir(droolsRepo) {
- checkout(githubscm.resolveRepository(droolsRepo, 'apache',
getDroolsBranch(), false))
+ checkout(githubscm.resolveRepository(droolsRepo, 'apache',
getDroolsBranch(), false, getGitAuthorCredsId()))
}
}
@@ -170,6 +170,10 @@ String getDroolsBranch() {
return env['DROOLS_BRANCH'] ?: 'main'
}
+String getGitAuthorCredsId() {
+ return env.GIT_AUTHOR_CREDS_ID
+}
+
void cleanContainers() {
cloud.cleanContainersAndImages('docker')
}
diff --git a/.ci/jenkins/project/Jenkinsfile.nightly
b/.ci/jenkins/project/Jenkinsfile.nightly
index de12457ed7..45dd9ec4a0 100644
--- a/.ci/jenkins/project/Jenkinsfile.nightly
+++ b/.ci/jenkins/project/Jenkinsfile.nightly
@@ -190,21 +190,21 @@ String getGitAuthor() {
return env.GIT_AUTHOR
}
-String getGitAuthorCredsID() {
- return env.AUTHOR_CREDS_ID
+String getGitAuthorCredsId() {
+ return env.GIT_AUTHOR_CREDS_ID
}
void checkoutNewBranch(String repo, String originBranch, String newBranch,
String dirName = repo) {
dir(dirName) {
deleteDir()
- checkout(githubscm.resolveRepository(repo, getGitAuthor(),
originBranch, false))
+ checkout(githubscm.resolveRepository(repo, getGitAuthor(),
originBranch, false, getGitAuthorCredsId()))
sh "git checkout -b ${newBranch}"
}
}
void forcePushBranch(String dirName, String branch) {
dir(dirName) {
- withCredentials([usernamePassword(credentialsId:
getGitAuthorCredsID(), usernameVariable: 'GIT_USERNAME', passwordVariable:
'GIT_PASSWORD')]) {
+ withCredentials([usernamePassword(credentialsId:
getGitAuthorCredsId(), usernameVariable: 'GIT_USERNAME', passwordVariable:
'GIT_PASSWORD')]) {
// Please leave the double-quote here. They are mandatory for the
shell command to work correctly.
sh """
git config --local credential.helper \"!f() { echo
username=\\$GIT_USERNAME; echo password=\\$GIT_PASSWORD; }; f\"
diff --git a/.ci/jenkins/project/Jenkinsfile.post-release
b/.ci/jenkins/project/Jenkinsfile.post-release
index 9163b57b86..77363329dc 100644
--- a/.ci/jenkins/project/Jenkinsfile.post-release
+++ b/.ci/jenkins/project/Jenkinsfile.post-release
@@ -124,7 +124,7 @@ pipeline {
// dir(websiteRepository) {
// checkoutRepo(websiteRepository, 'main')
// mergeAndPush(prLink, 'main')
- // githubscm.removeRemoteBranch('origin',
prBranchName, getGitAuthorCredsID())
+ // githubscm.removeRemoteBranch('origin',
prBranchName, getGitAuthorPushCredsId())
// }
// }
// }
@@ -178,8 +178,12 @@ String getGitAuthor() {
return env.GIT_AUTHOR
}
-String getGitAuthorCredsID() {
- return env.AUTHOR_CREDS_ID
+String getGitAuthorCredsId() {
+ return env.GIT_AUTHOR_CREDS_ID
+}
+
+String getGitAuthorPushCredsId() {
+ return env.GIT_AUTHOR_PUSH_CREDS_ID
}
String getSnapshotBranch() {
@@ -192,22 +196,22 @@ String getSnapshotBranch() {
void checkoutRepo(String repo, String branch) {
deleteDir()
- checkout(githubscm.resolveRepository(repo, getGitAuthor(), branch, false))
+ checkout(githubscm.resolveRepository(repo, getGitAuthor(), branch, false,
getGitAuthorCredsId()))
// need to manually checkout branch since on a detached branch after
checkout command
sh "git checkout ${branch}"
}
void checkoutTag(String repo, String tagName, String localBranchName =
tagName) {
deleteDir()
- checkout(githubscm.resolveRepository(repo, getGitAuthor(),
getBuildBranch(), false))
+ checkout(githubscm.resolveRepository(repo, getGitAuthor(),
getBuildBranch(), false, getGitAuthorCredsId()))
// Need to manually checkout branch since we are in 'detached HEAD' state
after the git checkout command.
sh "git checkout tags/${tagName} -b ${localBranchName}"
}
void mergeAndPush(String prLink, String targetBranch) {
if (prLink != '') {
- githubscm.mergePR(prLink, getGitAuthorCredsID())
- githubscm.pushObject('origin', targetBranch, getGitAuthorCredsID())
+ githubscm.mergePR(prLink, getGitAuthorCredsId())
+ githubscm.pushObject('origin', targetBranch, getGitAuthorPushCredsId())
}
}
@@ -215,8 +219,8 @@ String commitAndCreatePR(String commitMsg, Closure
precommit, String localBranch
def prBody = "Generated by build ${BUILD_TAG}: ${BUILD_URL}"
githubscm.commitChanges(commitMsg, precommit)
- githubscm.pushObject('origin', localBranch, getGitAuthorCredsID())
- return githubscm.createPR(commitMsg, prBody, targetBranch,
getGitAuthorCredsID())
+ githubscm.pushObject('origin', localBranch, getGitAuthorPushCredsId())
+ return githubscm.createPR(commitMsg, prBody, targetBranch,
getGitAuthorCredsId())
}
void commitAndForcePushBranch(String repo, String branch) {
@@ -268,7 +272,7 @@ void removeJbossNexusFromMavenAndGradle() {
}
def forcePushBranch(String branch) {
- withCredentials([usernamePassword(credentialsId: getGitAuthorCredsID(),
usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) {
+ withCredentials([usernamePassword(credentialsId: getGitAuthorCredsId(),
usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) {
// Please leave the double-quote here. They are mandatory for the
shell command to work correctly.
sh """
git config --local credential.helper \"!f() { echo
username=\\$GIT_USERNAME; echo password=\\$GIT_PASSWORD; }; f\"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]