// 下階層用テンプレート #topicpath ---- //ここにコンテンツを記述します。 #contents ** Jenkinsの抽象化されたjava.io.Fileである FilePath [#o7ffc559] ビルドのジョブが動くノード((マスターかスレーブか))によって、ワークスペースのパスは異なっていたりします。なのでJenkinsのファイルシステムはjava.io.Fileに似た FilePathというパスが抽象化されたクラスを使用します。以下サンプルコード。 @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { FilePath root = build.getModuleRoot(); // ワークスペースのルート.スレーブでビルドが動くと、他サーバのディレクトリだったりする。 FilePath fromFile = new FilePath(root, "from.txt"); System.out.println(fromFile); FilePath toFile = new FilePath(new FilePath(build.getRootDir()), "to.txt"); // ココはビルドのルートで、必ずMasterサーバ上にある System.out.println(toFile); fromFile.copyTo(toFile); // こんな感じにノード間でコピーできる。 // (このビルドがスレーブで動く場合、スレーブのワークスペースのファイルが、マスターサーバにコピーされたりする。) return true; } このように動いているサーバを抽象化し、ノード間のコピーもシームレスにできたりします。便利ですね。。 実行結果は [省略]/workspace/hoge/work/jobs/Test/workspace/from.txt [省略]/workspace/hoge/work/jobs/Test/builds/2015-09-25_13-12-45/to.txt となります。これはマスタで動いてしまいましたが、一行目はワークスペースなので場合によっては別ノードのパスになります。逆に二行目はビルドパスなので必ずマスターサーバのパスになります。 **プラグイン開発で使用する、Jenkins起動時のMAVEN_OPTS [#d6ea8734] export MAVEN_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n -Xmx1024m -XX:MaxPermSize=128m" Windowsだと set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n -Xmx1024m -XX:MaxPermSize=128m こうかな? **プラグイン開発で出てくる、ビルド関連のパス(FilePath/File)の結果 [#h36df304] System.out.println(build.getModuleRoot()); //FilePath ワークスペースのルート?リモートの場合もある。。 System.out.println(build.getRootDir()); //File このビルド自体のルート? System.out.println(build.getWorkspace()); //FilePath System.out.println(build.getArtifactsDir()); ←@Deprecated //File の結果ですが、ビルドはローカル(マスター)で実行されるかスレーブで実行されるか分からないので、実行される環境によって下記のように結果が異なります。 -ローカル(マスター)の結果(Windows) TESTというジョブを走らせた場合。 D:\workspace_palette\project-management\work\jobs\TEST\workspace D:\workspace_palette\project-management\.\work\jobs\TEST\builds\2014-10-17_12-46-07 D:\workspace_palette\project-management\work\jobs\TEST\workspace D:\workspace_palette\project-management\.\work\jobs\TEST\builds\2014-10-17_12-46-07\archive -スレーブの結果(Linux) TESTというジョブを走らせた場合。スレーブのトップディレクトリは /opt/jenkins/ に設定してあります。結果は以下 /opt/jenkins/workspace/TEST D:\workspace_palette\project-management\.\work\jobs\TEST\builds\2014-10-17_12-50-37 /opt/jenkins/workspace/TEST D:\workspace_palette\project-management\.\work\jobs\TEST\builds\2014-10-17_12-50-37\archive **Jenkinsのソース検索 [#g070d50c] [[GitHub>https://github.com/jenkinsci/jenkins/search]] にアクセスして 「検索文字列」 repo:jenkinsci/jenkins [検索文字]といれて検索を行えばOK ** ビルダーが追加したアクションのアイコンを指定する。 [#r4d697cc] XXBuilderクラスないで action = new XXAction(build); build.addAction(action); などとしてアクションを追加すると、そのビルド画面の左メニューにアイコンが表示されます。 #ref(menu.png) このアイコンを独自のモノにするには、 @Override public String getIconFileName() { return "/plugin/project-management/images/24x24/user_suit.png"; <- project-management はプラグイン名。 } などとしてファイル名を絶対パスで指定します。 この場所はプロジェクト上は #ref(icon.png) あたりに解釈されるので、ココにファイルを配置してビルドすればOKです。 [[Jenkins users - Plugin image location>http://jenkins-ci.361315.n4.nabble.com/Plugin-image-location-td362688.html]] **アクションの画面でのリンク [#g3e2a4b9] index.jelly 内のリンク設定: <a href="documents/hogehoge.tsv">hogehoge.tsv</a> だった場合、クリックするとアクションクラスの public void doDynamic(StaplerRequest req, StaplerResponse res) throws IOException, ServletException { } メソッドがコールされます。引数は通常のサーブレットのReq/Resのインタフェースになっています。 なので下記のようにResponseにデータを流し込んで String filePath = req.getRestOfPath(); filePathは documents/hogehoge.tsv File file = new File(owner.getRootDir(), filePath); ← rootDirはビルドのディレクトリ FileInputStream in = null; ServletOutputStream out = res.getOutputStream(); try { in = new FileInputStream(file); int i; while ((i = in.read()) != -1) { out.write(i); } } finally { out.close(); in.close(); } ビルドしたディレクトリにあるファイルを引っぱってきて直接表示したり、 res.sendRedirect2(req.getContextPath() + req.getRestOfPath()); /[contextpath]/documents/hogehoge.tsv などとして指定した画面へリダイレクトしたりすることができます。 **ビルドのトリガーとなったコミット情報にアクセスする。 [#l96c8684] public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) ないで、以下のようにアクセスすることができます。 if (build.getChangeSet() instanceof SubversionChangeLogSet) { SubversionChangeLogSet changeSet = (SubversionChangeLogSet) build .getChangeSet(); List<LogEntry> logs = changeSet.getLogs(); // 一回のコミットのログ for (LogEntry logEntry : logs) { List<Path> paths = logEntry.getPaths(); // 一回のコミットで複数のコミットファイルがある for (Path path : paths) { listener.getLogger().printf("[%s][%s][%s][%s]\n", path.getKind(), path.getValue(), path.getPath(), path.getEditType().getName()); } } } 実行結果: A test.dat At revision 347 [unknown][/trunk/test/test.dat][/trunk/test/test.dat][add] ビルドのトリガーとなったコミット情報((というか、そのビルドでUpdateされたコミット情報))へアクセスすることができました。 あ pom.xml に <dependency> <groupId>org.jenkins-ci.plugins</groupId> <artifactId>subversion</artifactId> <version>1.45</version> </dependency> の追加が必要です。。 **Jenkinsの設定を使ってE-Mailを送信する。 [#z5f9f65a] まずこんな感じにメールを送信するメソッドを定義します。 public static void sendMail(String[] addresses, String subject, String message) throws UnsupportedEncodingException, MessagingException { MimeMessage mimeMessage = new MimeMessage(Mailer.descriptor() .createSession()); InternetAddress[] to = new InternetAddress[addresses.length]; for (int i = 0; i < addresses.length; i++) { to[i] = new InternetAddress(addresses[i], true); } mimeMessage.setRecipients(Message.RecipientType.TO, to); mimeMessage.setSubject(subject, "ISO-2022-JP"); mimeMessage.setText(message, "ISO-2022-JP"); Transport.send(mimeMessage); } 基本的にはコレだけでJenkinsにあらかじめ設定されているメール送信設定を用いてメールを送ることができます。 あとは public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) 内で、以下のようにメール送信ができます。 listener.getLogger().printf("宛先: %s \n", addresses); listener.getLogger().printf("題名: %s \n", subject); listener.getLogger().printf("メッセージ: %s \n", message); String[] addressArray = StringUtils.stripAll(StringUtils.split( addresses, ',' )); try { sendMail(addressArray, subject, message); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } あ、pom.xml に <dependency> <groupId>org.jenkins-ci.plugins</groupId> <artifactId>mailer</artifactId> <version>1.5</version> </dependency> の追加が必要です。。 ---- この記事は #vote(おもしろかった,そうでもない) - こうみると、ワークスペースはスレーブにも存在するが、ビルドのディレクトリはマスターにしか存在しないってことになりますね。。スレーブで処理されてワークスペースになんかを出力した場合、それはスレーブに出力されるので、スレーブのワークスペースからビルドディレクトリにコピーする必要がありそうです。 -- [[きの]] &new{2014-11-27 (木) 16:52:44}; - b -- [[あ]] &new{2015-09-25 (金) 13:17:03}; #comment #topicpath SIZE(10){現在のアクセス:&counter;}