First commit
Some checks are pending
Jenkins Security Scan / security-scan (push) Waiting to run
/ update_release_draft (push) Waiting to run

This commit is contained in:
Gius95 2024-11-17 16:57:10 +01:00
commit c5b54c260a
31 changed files with 1281 additions and 0 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1 @@
* @jenkinsci/it.integry.pbautobuild-plugin-plugin-developers

12
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates
version: 2
updates:
- package-ecosystem: maven
directory: /
schedule:
interval: monthly
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly

2
.github/release-drafter.yml vendored Normal file
View File

@ -0,0 +1,2 @@
_extends: .github
tag-template: it.integry.pbautobuild-plugin-$NEXT_MINOR_VERSION

View File

@ -0,0 +1,23 @@
# More information about the Jenkins security scan can be found at the developer docs: https://www.jenkins.io/redirect/jenkins-security-scan/
name: Jenkins Security Scan
on:
push:
branches:
- "master"
- "main"
pull_request:
types: [ opened, synchronize, reopened ]
workflow_dispatch:
permissions:
security-events: write
contents: read
actions: read
jobs:
security-scan:
uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2
with:
java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate.
java-version: 17 # What version of Java to set up for the build.

17
.github/workflows/release-drafter.yml vendored Normal file
View File

@ -0,0 +1,17 @@
# Automates creation of Release Drafts using Release Drafter
# More Info: https://github.com/jenkinsci/.github/blob/master/.github/release-drafter.adoc
on:
push:
branches:
- master
- main
jobs:
update_release_draft:
runs-on: ubuntu-latest
steps:
# Drafts your next Release notes as Pull Requests are merged into the default branch
- uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
target
# mvn hpi:run
work
# IntelliJ IDEA project files
*.iml
*.iws
*.ipr
.idea
# Eclipse project files
.settings
.classpath
.project

7
.mvn/extensions.xml Normal file
View File

@ -0,0 +1,7 @@
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 https://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
<extension>
<groupId>io.jenkins.tools.incrementals</groupId>
<artifactId>git-changelist-maven-extension</artifactId>
<version>1.8</version>
</extension>
</extensions>

2
.mvn/maven.config Normal file
View File

@ -0,0 +1,2 @@
-Pconsume-incrementals
-Pmight-produce-incrementals

11
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,11 @@
/*
See the documentation for more options:
https://github.com/jenkins-infra/pipeline-library/
*/
buildPlugin(
forkCount: '1C', // run this number of tests in parallel for faster feedback. If the number terminates with a 'C', the value will be multiplied by the number of available CPU cores
useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests
configurations: [
[platform: 'linux', jdk: 21],
[platform: 'windows', jdk: 17],
])

9
LICENSE.md Normal file
View File

@ -0,0 +1,9 @@
The MIT License
Copyright 2024
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# it.integry.pbautobuild-plugin
## Introduction
TODO Describe what your plugin does here
## Getting started
TODO Tell users how to configure your plugin here, include screenshots, pipeline examples and
configuration-as-code examples.
## Issues
TODO Decide where you're going to host your issues, the default is Jenkins JIRA, but you can also enable GitHub issues,
If you use GitHub issues there's no need for this section; else add the following line:
Report issues and enhancements in the [Jenkins issue tracker](https://issues.jenkins.io/).
## Contributing
TODO review the default [CONTRIBUTING](https://github.com/jenkinsci/.github/blob/master/CONTRIBUTING.md) file and make sure it is appropriate for your plugin, if not then add your own one adapted from the base file
Refer to our [contribution guidelines](https://github.com/jenkinsci/.github/blob/master/CONTRIBUTING.md)
## LICENSE
Licensed under MIT, see [LICENSE](LICENSE.md)

96
pom.xml Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.85</version>
<relativePath/>
</parent>
<groupId>io.jenkins.plugins</groupId>
<artifactId>it.integry.pbautobuild-plugin</artifactId>
<version>${revision}${changelist}</version>
<packaging>hpi</packaging>
<name>PowerBuilder 2022 AutoBuild Plugin</name>
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>
<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/license/mit/</url>
</license>
</licenses>
<scm child.scm.connection.inherit.append.path="false" child.scm.developerConnection.inherit.append.path="false"
child.scm.url.inherit.append.path="false">
<connection>scm:git:https://github.com/${gitHubRepo}</connection>
<developerConnection>scm:git:https://github.com/${gitHubRepo}</developerConnection>
<tag>${scmTag}</tag>
<url>https://github.com/${gitHubRepo}</url>
</scm>
<properties>
<revision>1.0.3</revision>
<changelist>-SNAPSHOT</changelist>
<!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->
<jenkins.version>2.440.3</jenkins.version>
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
<spotless.check.skip>false</spotless.check.skip>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Pick up common dependencies for the selected LTS line: https://github.com/jenkinsci/bom#usage -->
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.440.x</artifactId>
<version>3193.v330d8248d39e</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-basic-steps</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-durable-task-step</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</project>

View File

@ -0,0 +1,422 @@
package io.jenkins.plugins.sample;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.*;
import hudson.model.*;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import hudson.tools.ToolInstallation;
import hudson.util.ArgumentListBuilder;
import jenkins.tasks.SimpleBuildStep;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
public class PBAutoBuildBuilder extends Builder implements SimpleBuildStep {
/**
* GUI fields
*/
private String pbAutoBuildName;
private String cmdLineArgs;
private boolean continueOnBuildFailure;
private boolean unstableIfWarnings;
/**
* When this builder is created in the project configuration step, the
* builder object will be created from the strings below.
*
* @param pbAutoBuildName
* The PowerBuilder logical name
* @param cmdLineArgs
* Whitespace separated list of command line arguments for pb autobuild utility
* @param continueOnBuildFailure
* If true, job will continue despite pb autobuild build failure
* @param unstableIfWarnings
* If true, job will be unstable if there are warnings
*/
@DataBoundConstructor
public PBAutoBuildBuilder(String pbAutoBuildName, String cmdLineArgs, boolean continueOnBuildFailure, boolean unstableIfWarnings) {
this.pbAutoBuildName = pbAutoBuildName;
this.cmdLineArgs = cmdLineArgs;
this.continueOnBuildFailure = continueOnBuildFailure;
this.unstableIfWarnings = unstableIfWarnings;
}
public String getPbAutoBuildName() {
return pbAutoBuildName;
}
@DataBoundSetter
public void setPbAutoBuildName(String pbAutoBuildName) {
this.pbAutoBuildName = pbAutoBuildName;
}
public String getCmdLineArgs() {
return cmdLineArgs;
}
@DataBoundSetter
public void setCmdLineArgs(String cmdLineArgs) {
this.cmdLineArgs = cmdLineArgs;
}
public boolean isContinueOnBuildFailure() {
return continueOnBuildFailure;
}
@DataBoundSetter
public void setContinueOnBuildFailure(boolean continueOnBuildFailure) {
this.continueOnBuildFailure = continueOnBuildFailure;
}
public boolean isUnstableIfWarnings() {
return unstableIfWarnings;
}
@DataBoundSetter
public void setUnstableIfWarnings(boolean unstableIfWarnings) {
this.unstableIfWarnings = unstableIfWarnings;
}
public PBAutoBuildInstallation getPBAutoBuild() {
DescriptorImpl descriptor = (DescriptorImpl) getDescriptor();
for (PBAutoBuildInstallation i : descriptor.getInstallations()) {
if (pbAutoBuildName != null && i.getName().equals(pbAutoBuildName))
return i;
}
if ( descriptor.getInstallations().length == 1 ) {
return descriptor.getInstallations()[0];
}
return null;
}
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
throws InterruptedException, IOException {
return runPBAutoBuild(build, build.getWorkspace(), launcher, listener);
}
@Override
public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNull EnvVars env, @NonNull Launcher launcher, @NonNull TaskListener listener) throws InterruptedException, IOException {
runPBAutoBuild(run, workspace, launcher, listener);
}
public boolean runPBAutoBuild(Run<?, ?> build, @NonNull FilePath workspace, Launcher launcher, TaskListener listener)
throws InterruptedException, IOException {
ArgumentListBuilder args = new ArgumentListBuilder();
PBAutoBuildInstallation ai = getPBAutoBuild();
String execName = "pbautobuild220.exe";
if (ai == null) {
listener.fatalError("Unable to find a valid installation");
} else {
EnvVars env = build.getEnvironment(listener);
//Node node = Computer.currentComputer().getNode();
//if (node != null) {
//ai = ai.forNode(node, listener);
ai = ai.forEnvironment(env);
String pathToPBAutoBuild = getToolFullPath(launcher, ai.getHome(), execName);
FilePath exec = new FilePath(launcher.getChannel(), pathToPBAutoBuild);
try {
if (!exec.exists()) {
listener.fatalError(pathToPBAutoBuild + " doesn't exist");
return false;
}
} catch (IOException e) {
listener.fatalError("Failed checking for existence of " + pathToPBAutoBuild);
return false;
}
listener.getLogger().println("Path to PB AutoBuild utility: " + pathToPBAutoBuild);
args.add(pathToPBAutoBuild);
if (ai.getDefaultArgs() != null) {
args.add(tokenizeArgs(ai.getDefaultArgs()));
}
//}
}
EnvVars env = build.getEnvironment(listener);
String normalizedArgs = cmdLineArgs.replaceAll("[\t\r\n]+", " ");
normalizedArgs = Util.replaceMacro(normalizedArgs, env);
//normalizedArgs = Util.replaceMacro(normalizedArgs, build.getBuildVariables());
if (!normalizedArgs.trim().isEmpty())
args.add(tokenizeArgs(normalizedArgs));
if (!launcher.isUnix()) {
final int cpi = getCodePageIdentifier(build.getCharset());
if (cpi != 0)
args.prepend("cmd.exe", "/C", "\"", "chcp", String.valueOf(cpi), "&&");
else
args.prepend("cmd.exe", "/C", "\"");
args.add("\"", "&&", "exit", "%%ERRORLEVEL%%");
}
try {
listener.getLogger()
.println(String.format("Executing the command %s from %s", args.toStringWithQuote(), workspace));
// Parser to find the number of Warnings/Errors
PBAutoBuildConsoleParser mbcp = new PBAutoBuildConsoleParser(listener.getLogger(), build.getCharset());
PBAutoBuildConsoleAnnotator annotator = new PBAutoBuildConsoleAnnotator(listener.getLogger(),
build.getCharset(), false);
// Launch the pbautobuild utility
int r = launcher.launch().cmds(args).envs(env).stdout(mbcp).stdout(annotator).pwd(workspace).join();
// Check the number of warnings
if (unstableIfWarnings && mbcp.getNumberOfWarnings() > 0) {
listener.getLogger().println("> Set build UNSTABLE because there are warnings.");
build.setResult(Result.UNSTABLE);
}
// Return the result of the compilation
return continueOnBuildFailure || (r == 0);
} catch (IOException e) {
Util.displayIOException(e, listener);
build.setResult(Result.FAILURE);
return false;
}
}
/**
* Get the full path of the tool to run. If given path is a directory, this
* will append the executable name.
*/
static String getToolFullPath(Launcher launcher, String pathToTool, String execName)
throws IOException, InterruptedException {
String fullPath = pathToTool;
FilePath exec = new FilePath(launcher.getChannel(), fullPath);
if (exec.isDirectory()) {
if (!fullPath.endsWith("\\")) {
fullPath = fullPath + "\\";
}
fullPath = fullPath + execName;
}
return fullPath;
}
@Override
public Descriptor<Builder> getDescriptor() {
return super.getDescriptor();
}
/**
* Tokenize a set of arguments, preserving quotes.
*
* @param args
* @return
*/
static String[] tokenizeArgs(String args) {
if (args == null) {
return null;
}
final String[] tokenize = Util.tokenize(args);
if (args.endsWith("\\")) {
tokenize[tokenize.length - 1] = tokenize[tokenize.length - 1] + "\\";
}
return tokenize;
}
@Extension
@Symbol("pbautobuild")
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
@CopyOnWrite
private volatile PBAutoBuildInstallation[] installations = new PBAutoBuildInstallation[0];
public DescriptorImpl() {
super(PBAutoBuildBuilder.class);
load();
}
@Override
public String getDisplayName() {
return Messages.PBAutoBuildBuilder_DisplayName();
}
@SuppressWarnings("rawtypes")
@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}
public PBAutoBuildInstallation[] getInstallations() {
return Arrays.copyOf(installations, installations.length);
}
public void setInstallations(PBAutoBuildInstallation... antInstallations) {
this.installations = antInstallations;
save();
}
public PBAutoBuildInstallation.DescriptorImpl getToolDescriptor() {
return ToolInstallation.all().get(PBAutoBuildInstallation.DescriptorImpl.class);
}
}
private static int getCodePageIdentifier(Charset charset) {
final String s_charset = charset.name();
if (s_charset.equalsIgnoreCase("utf-8")) // Unicode
return 65001;
else if (s_charset.equalsIgnoreCase("ibm437")) // US
return 437;
else if (s_charset.equalsIgnoreCase("ibm850")) // OEM Multilingual Latin
// 1
return 850;
else if (s_charset.equalsIgnoreCase("ibm852")) // OEM Latin2
return 852;
else if (s_charset.equalsIgnoreCase("shift_jis") || s_charset.equalsIgnoreCase("windows-31j")) // Japanese
return 932;
else if (s_charset.equalsIgnoreCase("us-ascii")) // US-ASCII
return 20127;
else if (s_charset.equalsIgnoreCase("euc-jp")) // Japanese
return 20932;
else if (s_charset.equalsIgnoreCase("iso-8859-1")) // Latin 1
return 28591;
else if (s_charset.equalsIgnoreCase("iso-8859-2")) // Latin 2
return 28592;
else if (s_charset.equalsIgnoreCase("IBM00858"))
return 858;
else if (s_charset.equalsIgnoreCase("IBM775"))
return 775;
else if (s_charset.equalsIgnoreCase("IBM855"))
return 855;
else if (s_charset.equalsIgnoreCase("IBM857"))
return 857;
else if (s_charset.equalsIgnoreCase("ISO-8859-4"))
return 28594;
else if (s_charset.equalsIgnoreCase("ISO-8859-5"))
return 28595;
else if (s_charset.equalsIgnoreCase("ISO-8859-7"))
return 28597;
else if (s_charset.equalsIgnoreCase("ISO-8859-9"))
return 28599;
else if (s_charset.equalsIgnoreCase("ISO-8859-13"))
return 28603;
else if (s_charset.equalsIgnoreCase("ISO-8859-15"))
return 28605;
else if (s_charset.equalsIgnoreCase("KOI8-R"))
return 20866;
else if (s_charset.equalsIgnoreCase("KOI8-U"))
return 21866;
else if (s_charset.equalsIgnoreCase("UTF-16"))
return 1200;
else if (s_charset.equalsIgnoreCase("UTF-32"))
return 12000;
else if (s_charset.equalsIgnoreCase("UTF-32BE"))
return 12001;
else if (s_charset.equalsIgnoreCase("windows-1250"))
return 1250;
else if (s_charset.equalsIgnoreCase("windows-1251"))
return 1251;
else if (s_charset.equalsIgnoreCase("windows-1252"))
return 1252;
else if (s_charset.equalsIgnoreCase("windows-1253"))
return 1253;
else if (s_charset.equalsIgnoreCase("windows-1254"))
return 1254;
else if (s_charset.equalsIgnoreCase("windows-1257"))
return 1257;
else if (s_charset.equalsIgnoreCase("Big5"))
return 950;
else if (s_charset.equalsIgnoreCase("EUC-KR"))
return 51949;
else if (s_charset.equalsIgnoreCase("GB18030"))
return 54936;
else if (s_charset.equalsIgnoreCase("GB2312"))
return 936;
else if (s_charset.equalsIgnoreCase("IBM-Thai"))
return 20838;
else if (s_charset.equalsIgnoreCase("IBM01140"))
return 1140;
else if (s_charset.equalsIgnoreCase("IBM01141"))
return 1141;
else if (s_charset.equalsIgnoreCase("IBM01142"))
return 1142;
else if (s_charset.equalsIgnoreCase("IBM01143"))
return 1143;
else if (s_charset.equalsIgnoreCase("IBM01144"))
return 1144;
else if (s_charset.equalsIgnoreCase("IBM01145"))
return 1145;
else if (s_charset.equalsIgnoreCase("IBM01146"))
return 1146;
else if (s_charset.equalsIgnoreCase("IBM01147"))
return 1147;
else if (s_charset.equalsIgnoreCase("IBM01148"))
return 1148;
else if (s_charset.equalsIgnoreCase("IBM01149"))
return 1149;
else if (s_charset.equalsIgnoreCase("IBM037"))
return 37;
else if (s_charset.equalsIgnoreCase("IBM1026"))
return 1026;
else if (s_charset.equalsIgnoreCase("IBM273"))
return 20273;
else if (s_charset.equalsIgnoreCase("IBM277"))
return 20277;
else if (s_charset.equalsIgnoreCase("IBM278"))
return 20278;
else if (s_charset.equalsIgnoreCase("IBM280"))
return 20280;
else if (s_charset.equalsIgnoreCase("IBM284"))
return 20284;
else if (s_charset.equalsIgnoreCase("IBM285"))
return 20285;
else if (s_charset.equalsIgnoreCase("IBM297"))
return 20297;
else if (s_charset.equalsIgnoreCase("IBM420"))
return 20420;
else if (s_charset.equalsIgnoreCase("IBM424"))
return 20424;
else if (s_charset.equalsIgnoreCase("IBM500"))
return 500;
else if (s_charset.equalsIgnoreCase("IBM860"))
return 860;
else if (s_charset.equalsIgnoreCase("IBM861"))
return 861;
else if (s_charset.equalsIgnoreCase("IBM863"))
return 863;
else if (s_charset.equalsIgnoreCase("IBM864"))
return 864;
else if (s_charset.equalsIgnoreCase("IBM865"))
return 865;
else if (s_charset.equalsIgnoreCase("IBM869"))
return 869;
else if (s_charset.equalsIgnoreCase("IBM870"))
return 870;
else if (s_charset.equalsIgnoreCase("IBM871"))
return 20871;
else if (s_charset.equalsIgnoreCase("ISO-2022-JP"))
return 50220;
else if (s_charset.equalsIgnoreCase("ISO-2022-KR"))
return 50225;
else if (s_charset.equalsIgnoreCase("ISO-8859-3"))
return 28593;
else if (s_charset.equalsIgnoreCase("ISO-8859-6"))
return 28596;
else if (s_charset.equalsIgnoreCase("ISO-8859-8"))
return 28598;
else if (s_charset.equalsIgnoreCase("windows-1255"))
return 1255;
else if (s_charset.equalsIgnoreCase("windows-1256"))
return 1256;
else if (s_charset.equalsIgnoreCase("windows-1258"))
return 1258;
else
return 0;
}
}

View File

@ -0,0 +1,148 @@
package io.jenkins.plugins.sample;
import hudson.console.LineTransformationOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PBAutoBuildConsoleAnnotator extends LineTransformationOutputStream {
private final OutputStream out;
private final Charset charset;
private final boolean verboseLogging;
private final PBAutoBuildErrorNote errorNote = new PBAutoBuildErrorNote();
private final PBAutoBuildWarningNote warningNote = new PBAutoBuildWarningNote();
private int numberOfWarnings = 0;
private int numberOfErrors = 0;
// Pattern per Versione e Runtime
private Pattern versionPattern = Pattern.compile("PBAutoBuild Version: ([\\d\\.]+)");
private Pattern runtimePattern = Pattern.compile("Runtime Version: ([\\d\\.]+)");
// Pattern per Work Path
private Pattern workPathPattern = Pattern.compile("Work Path: (.+\\.exe)");
// Pattern per i progetti
private Pattern projectPattern = Pattern.compile("Deploying project ([a-zA-Z0-9_]+)");
// Pattern per i file (solo nome, escludendo il percorso)
private Pattern fileNamePattern = Pattern.compile("([^\\\\]+\\.\\w+)$");
// Pattern per Stage1, Stage2 e Regenerating
private Pattern stagePattern = Pattern.compile("(Normal|Stage1|Stage2|Regenerating) for ([a-zA-Z]:\\\\.*?\\\\([^\\\\]+\\.\\w+))");
public PBAutoBuildConsoleAnnotator(OutputStream out, Charset charset, boolean verboseLogging) {
this.out = out;
this.charset = charset;
this.verboseLogging = verboseLogging;
}
public int getNumberOfWarnings() {
return numberOfWarnings;
}
public int getNumberOfErrors() {
return numberOfErrors;
}
@Override
protected void eol(byte[] b, int len) throws IOException {
String line = charset.decode(ByteBuffer.wrap(b, 0, len)).toString();
byte[] bytes1 = line.getBytes(charset);
String lineUtf16 = StandardCharsets.UTF_16.decode(ByteBuffer.wrap(b, 0, len)).toString();
boolean isUtf16 = true;
for(int i = 0; i < bytes1.length; i = i+2) {
if(bytes1[i] != 0) {
isUtf16 = false;
break;
}
}
if(isUtf16) {
line = lineUtf16;
}
// trim off CR/LF from the end
line = trimEOL(line);
// Error messages handler
Matcher m = PBAutoBuildErrorNote.PATTERN.matcher(line);
if (m.matches()) { // Match the number of warnings
errorNote.encodeTo(out);
this.numberOfErrors++;
}
// Warning messages handler
m = PBAutoBuildWarningNote.PATTERN.matcher(line);
if (m.matches()) { // Match the number of warnings
warningNote.encodeTo(out);
this.numberOfWarnings++;
}
if(verboseLogging)
out.write(b, 0, len);
else {
// Estrarre i dati
String version = extractData(line, versionPattern);
String runtimePath = extractData(line, runtimePattern);
String workPath = extractData(line, workPathPattern);
String project = extractData(line, projectPattern);
String filename = extractFileNames(line, fileNamePattern);
String stage = extractStages(line, stagePattern);
if(line.contains("[Normal]")) {
//if(line.contains("\\"))
// line = line.substring(line.lastIndexOf("\\"));
byte[] bytesToWrite = line.getBytes(charset);
out.write(bytesToWrite, 0, bytesToWrite.length);
}
}
}
@Override
public void close() throws IOException {
super.close();
out.close();
}
private String extractData(String log, Pattern pattern) {
Matcher matcher = pattern.matcher(log);
if (matcher.matches()) {
return matcher.group(1);
}
return null;
}
private String extractFileNames(String log, Pattern pattern) {
Matcher matcher = pattern.matcher(log);
if (matcher.find()) {
return matcher.group(1); // Nome del file senza percorso
}
return null;
}
private String extractStages(String log, Pattern pattern) {
Matcher matcher = pattern.matcher(log);
if (matcher.find()) {
return "[" + matcher.group(1) + "] " + matcher.group(3); // Stage (Stage1, Stage2, ecc.)
}
return null;
}
}

View File

@ -0,0 +1,97 @@
package io.jenkins.plugins.sample;
/*
* The MIT License (MIT)
*
* Copyright (c) 2014, Kyle Sweeney, Gregory Boissinot and other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import hudson.console.LineTransformationOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Parser to find the number of Warnings/Errors of PBAutoBild compilation
*
* @author Damien Finck
*/
public class PBAutoBuildConsoleParser extends LineTransformationOutputStream {
private final OutputStream out;
private final Charset charset;
private int numberOfWarnings = -1;
private int numberOfErrors = -1;
public PBAutoBuildConsoleParser(OutputStream out, Charset charset) {
this.out = out;
this.charset = charset;
}
public int getNumberOfWarnings() {
return numberOfWarnings;
}
public int getNumberOfErrors() {
return numberOfErrors;
}
@Override
protected void eol(byte[] b, int len) throws IOException {
String line = charset.decode(ByteBuffer.wrap(b, 0, len)).toString();
// trim off CR/LF from the end
line = trimEOL(line);
Pattern patternWarnings = Pattern.compile(".*\\d+\\sWarning\\(s\\).*");
Pattern patternErrors = Pattern.compile(".*\\d+\\sError\\(s\\).*");
Matcher mWarnings = patternWarnings.matcher(line);
Matcher mErrors = patternErrors.matcher(line);
if (mWarnings.matches()) { // Match the number of warnings
String[] part = line.split(" ");
try {
numberOfWarnings = Integer.parseInt(part[4]);
} catch (NumberFormatException e) {
}
} else if (mErrors.matches()) { // Match the number of errors
String[] part = line.split(" ");
try {
numberOfErrors = Integer.parseInt(part[4]);
} catch (NumberFormatException e) {
}
}
// Write to output
out.write(b, 0, len);
}
@Override
public void close() throws IOException {
super.close();
out.close();
}
}

View File

@ -0,0 +1,42 @@
package io.jenkins.plugins.sample;
import hudson.Extension;
import hudson.MarkupText;
import hudson.console.ConsoleAnnotationDescriptor;
import hudson.console.ConsoleAnnotator;
import hudson.console.ConsoleNote;
import org.jenkinsci.Symbol;
import java.util.regex.Pattern;
/**
* Annotation for PB AutoBuild error messages
*/
@SuppressWarnings("rawtypes")
public class PBAutoBuildErrorNote extends ConsoleNote {
/**
*
*/
private static final long serialVersionUID = -3278523238642788774L;
/** Pattern to identify error messages */
public final static Pattern PATTERN = Pattern.compile("(.*)[Ee]rror\\s(([A-Z]*)\\d+){0,1}:\\s(.*)");
public PBAutoBuildErrorNote() {
}
@Override
public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) {
text.addMarkup(0, text.length(), "<span class=error-inline>", "</span>");
return null;
}
@Extension @Symbol("pbAutoBuildError")
public static final class DescriptorImpl extends ConsoleAnnotationDescriptor {
@Override
public String getDisplayName() {
return Messages.PBAutoBuildBuilder_ErrorNoteDescription();
}
}
}

View File

@ -0,0 +1,102 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014, Kyle Sweeney, Gregory Boissinot and other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.sample;
import hudson.EnvVars;
import hudson.Extension;
import hudson.Util;
import hudson.model.EnvironmentSpecific;
import hudson.model.Node;
import hudson.model.TaskListener;
import hudson.slaves.NodeSpecific;
import hudson.tools.ToolDescriptor;
import hudson.tools.ToolInstallation;
import jenkins.model.Jenkins;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import java.io.IOException;
/**
* @author Gregory Boissinot
*/
public final class PBAutoBuildInstallation extends ToolInstallation implements NodeSpecific<PBAutoBuildInstallation>, EnvironmentSpecific<PBAutoBuildInstallation> {
/**
*
*/
private static final long serialVersionUID = -9032399700618715657L;
private final String defaultArgs;
@DataBoundConstructor
public PBAutoBuildInstallation(String name, String home, String defaultArgs) {
super(name, home, null);
this.defaultArgs = Util.fixEmpty(defaultArgs);
}
@Override
public PBAutoBuildInstallation forNode(Node node, TaskListener log) throws IOException, InterruptedException {
return new PBAutoBuildInstallation(getName(), translateFor(node, log), getDefaultArgs());
}
@Override
public PBAutoBuildInstallation forEnvironment(EnvVars environment) {
return new PBAutoBuildInstallation(getName(), environment.expand(getHome()), getDefaultArgs());
}
public String getDefaultArgs() {
return this.defaultArgs;
}
@Extension @Symbol("pbautobuild")
public static class DescriptorImpl extends ToolDescriptor<PBAutoBuildInstallation> {
@Override
public String getDisplayName() {
return "PBAutoBuild 2022";
}
@Override
public PBAutoBuildInstallation[] getInstallations() {
return getDescriptor().getInstallations();
}
@Override
public void setInstallations(PBAutoBuildInstallation... installations) {
getDescriptor().setInstallations(installations);
}
private PBAutoBuildBuilder.DescriptorImpl getDescriptor() {
Jenkins jenkins = Jenkins.getInstanceOrNull();
if (jenkins != null && jenkins.getDescriptorByType(PBAutoBuildBuilder.DescriptorImpl.class) != null) {
return jenkins.getDescriptorByType(PBAutoBuildBuilder.DescriptorImpl.class);
} else {
// To stick with current behavior and meet findbugs requirements
throw new NullPointerException(jenkins == null ? "Jenkins instance is null" : "PBAutoBuildBuilder.DescriptorImpl is null");
}
}
}
}

View File

@ -0,0 +1,44 @@
package io.jenkins.plugins.sample;
import hudson.Extension;
import hudson.util.ProcessKillingVeto;
import hudson.util.ProcessTreeRemoting.IOSProcess;
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.jenkinsci.Symbol;
/**
* An extension that avoids mspdbsrv.exe being killed by Jenkins.
*
* Requires a Jenkins version &gt;= 1.619. Will simply be ignored for older versions.
*
* See JENKINS-9104
*
* @author Daniel Weber &lt;daniel.weber.dev@gmail.com&gt;
*/
@Extension(optional = true) @Symbol("pbAutoBuildKillingVeto")
public class PBAutoBuildKillingVeto extends ProcessKillingVeto {
private static final VetoCause VETO_CAUSE = new VetoCause("PBAutoBuild Plugin vetoes killing <name of process>");
/**
*
*/
@Override
public VetoCause vetoProcessKilling(IOSProcess proc) {
if (proc == null)
return null;
List<String> cmdLine = proc.getArguments();
if (cmdLine == null || cmdLine.isEmpty())
return null;
String command = cmdLine.get(0);
String exeName = FilenameUtils.getName(command);
if (exeName.equalsIgnoreCase("<somefile.exe>")) {
return VETO_CAUSE;
}
return null;
}
}

View File

@ -0,0 +1,44 @@
package io.jenkins.plugins.sample;
import hudson.Extension;
import hudson.MarkupText;
import hudson.console.ConsoleAnnotationDescriptor;
import hudson.console.ConsoleAnnotator;
import hudson.console.ConsoleNote;
import org.jenkinsci.Symbol;
import java.util.regex.Pattern;
import static io.jenkins.plugins.sample.Messages.*;
/**
* Annotation for PB AutoBuild warning messages
*/
@SuppressWarnings("rawtypes")
public class PBAutoBuildWarningNote extends ConsoleNote {
/**
*
*/
private static final long serialVersionUID = 5058082724408336863L;
/** Pattern to identify warning messages */
public final static Pattern PATTERN = Pattern.compile("(.*)\\(\\d+(,\\d+){0,1}\\):\\s[Ww]arning\\s(([A-Z]*)\\d+){0,1}:\\s(.*)");
public PBAutoBuildWarningNote() {
}
@Override
public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) {
text.addMarkup(0, text.length(), "<span class=warning-inline>", "</span>");
return null;
}
@Extension @Symbol("pbAutoBuildWarning")
public static final class DescriptorImpl extends ConsoleAnnotationDescriptor {
@Override
public String getDisplayName() {
return Messages.PBAutoBuildBuilder_WarningNoteDescription();
}
}
}

View File

@ -0,0 +1,4 @@
<?jelly escape-by-default='true'?>
<div>
This plugin makes it possible to build a PowerBuilder target (.pbt) using the PowerBuilder PBAutoBuild utility
</div>

View File

@ -0,0 +1,25 @@
# The MIT License
#
# Copyright (c) 2014, Damien Finck
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
PBAutoBuildBuilder.DisplayName=Build a PowerBuilder target using PBAutoBuild
PBAutoBuildBuilder.ErrorNoteDescription=PBAutoBuild error
PBAutoBuildBuilder.WarningNoteDescription=PBAutoBuild warning

View File

@ -0,0 +1,5 @@
HelloWorldBuilder.DescriptorImpl.errors.missingName=Bitte geben Sie einen Namen an
HelloWorldBuilder.DescriptorImpl.warnings.tooShort=Der Name ist zu kurz.
HelloWorldBuilder.DescriptorImpl.warnings.reallyFrench=Sind Sie wirklich französisch?
HelloWorldBuilder.DescriptorImpl.DisplayName="Hallo Welt" sagen

View File

@ -0,0 +1,46 @@
<!--
The MIT License (MIT)
Copyright (c) 2014, Kyle Sweeney, Gregory Boissinot and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler">
<f:entry title="${%Instance}" field="pbAutoBuildName">
<select name="PBAutoBuildBuilder.pbAutoBuildName">
<j:forEach var="installation" items="${descriptor.installations}">
<f:option value="${installation.name}">${installation.name}</f:option>
</j:forEach>
</select>
</f:entry>
<f:entry title="${%Additional command line arguments}" field="cmdLineArgs">
<f:textarea name="pbAutoBuildBuilder.cmdLineArgs" value="${instance.cmdLineArgs}"/>
</f:entry>
<f:advanced>
<f:entry title="${%Continue Job on build Failure}" field="continueOnBuildFailure">
<f:checkbox name="pbAutoBuildBuilder.continueOnBuildFailure" value="${instance.continueOnBuildFailure}"
checked="${instance.continueOnBuildFailure}" default="false"/>
</f:entry>
<f:entry title="${%If warnings set the build to Unstable}" field="unstableIfWarnings">
<f:checkbox name="pbAutoBuildBuilder.unstableIfWarnings" value="${instance.unstableIfWarnings}"
checked="${instance.unstableIfWarnings}" default="false"/>
</f:entry>
</f:advanced>
</j:jelly>

View File

@ -0,0 +1,9 @@
<div>
<p>
If set to true, Jenkins build variables will be passed to PBAutoBuild utility as /p:name=value pairs.
</p>
<p>
<strong>Beware :</strong> Sensitive build variables such as passwords will not be added.
</p>
</div>

View File

@ -0,0 +1,6 @@
<div>
<p>
This is a whitespace separated-list of command-line arguments you can specify.
These can be the same as if you were to run the PBAutoBuild utility from the command line.
</p>
</div>

View File

@ -0,0 +1,5 @@
<div>
<p>
If set to true, Job will continue despite PBAutoBuild build failure.
</p>
</div>

View File

@ -0,0 +1,7 @@
<div>
<p>
Give the .pbt from the project root (SCM root directory or workspace directory) that PBAutoBuild will
use to build.<br/>
You can use build variables through the syntax ${var}.
</p>
</div>

View File

@ -0,0 +1,5 @@
<div>
<p>
If set to true and warnings on compilation, the build will be unstable.
</p>
</div>

View File

@ -0,0 +1,36 @@
<!--
The MIT License (MIT)
Copyright (c) 2014, Kyle Sweeney, Gregory Boissinot and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core"
xmlns:f="/lib/form">
<f:entry title="${%Name}" field="name">
<f:textbox/>
</f:entry>
<f:entry title="${%Path to PBAutoBuild utility}" field="home">
<f:textbox/>
</f:entry>
<f:entry title="${%Default parameters}" field="defaultArgs">
<f:textbox/>
</f:entry>
</j:jelly>

View File

@ -0,0 +1,5 @@
<div>
<p>
Specify default parameters to pass to all PBAutoBuild tasks.
</p>
</div>

View File

@ -0,0 +1,6 @@
<div>
<p>
Specify the path to your PBAutoBuild executable. <br/>
It is usually located at C:\Program Files (x86)\Appeon\Shared\PowerBuilder or C:\Program Files (x86)\Appeon\AutoCompiler 19.0
</p>
</div>