KISS

Be Among the 20% of the Best!

Jenkins: Matrix Job With Conditions

| comments

Let’s say I have an iOS project, and I’d like to build it in a number of configurations: “Debug”/“Release”, for device/simulator, and with/without debug logs. Jenkins has the multi-configuration (aka matrix) project build plugin for that. Not all of the steps are required/possible everywhere (e.g., testing is allowed in the simulator only, or checking the license is enough one time only).

Source Code License Check in Jenkins: Revised

| comments

This is a revised post on how to setup source code license check on your Jenkins. The first version is here. The basic idea is the same, but there are a few important changes described below. So to set this up, please follow the first post, except for a few values overridden here.

Jenkins: CocoaPods Podspec Linter

| comments

It’s a quick post on how I set up a build step to lint a podspec file. Quick check: if you’re not using CocoaPods to manage your iOS projects yet, you should try it (read on how to install it with rbenv here! So a podspec is a simple file that describes how your library’s metadata and how to include it in an app.

Objective-C: Weird Retain Cycle Warning

| comments

I was writing unit tests for an iOS project recently when I stumbled upon a very weird issue with a retain cycle warning from Clang. I created a minimal sample file to demonstrate it:

(retain_cycle_sample.m) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//
//  main.m
//  RetainCycleWarning
//
//  Created by u on 2015-04-04.
//  Copyright (c) 2015 yes. All rights reserved.
//

#import <Foundation/Foundation.h>
@import XCTest;


@interface Foo : NSObject

typedef void (^SuccessBlock)(CGFloat value);

- (void)setValue:(CGFloat)value
         success:(SuccessBlock)success;
- (void)getValueWithSuccessBlock:(SuccessBlock)success;

@end

@implementation Foo

- (void)setValue:(CGFloat)value
          success:(SuccessBlock)success {
}

- (void)getValueWithSuccessBlock:(SuccessBlock)success {
}

@end



@interface mainTests : XCTestCase

// used in multiple tests
@property (nonatomic, strong) Foo *foo;

@end

@implementation mainTests

- (void)setUp {
    [super setUp];
    self.foo = [Foo new];
}

- (void)tearDown {
    self.foo = nil;
    [super tearDown];
}

- (void)testFoo {
    [self.foo getValueWithSuccessBlock:^(CGFloat value) {
        XCTFail(@"success");
    }];

    [self.foo setValue:1.0
               success:^(CGFloat value) {
                   XCTFail(@"success");
               }];
}

@end



int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
    }
    return 0;
}

It’s the only file in a OS X command-line tool project. It has the Foo class with two simple methods to get and set a value, with empty implementations. Then, in a test class I create a property for a Foo object (because it’s originally used in multiple test methods), and test that the success blocks are not called. You don’t need to run the tests, because the point is this warning while building:

1
2
3
4
5
6
7
8
9
10
11
CompileC Library/Developer/Xcode/DerivedData/RetainCycleWarning-x/Build/Intermediates/RetainCycleWarning.build/Debug/RetainCycleWarning.build/Objects-normal/x86_64/main.o RetainCycleWarning/main.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
// …

RetainCycleWarning/RetainCycleWarning/main.m:62:20: warning: capturing 'self' strongly in this block is likely to lead to a retain cycle [-Warc-retain-cycles]
                   XCTFail(@"success");
                   ^~~~~~~~~~~~~~~~~~~
// …
RetainCycleWarning/RetainCycleWarning/main.m:60:6: note: block will be retained by an object strongly retained by the captured object
    [self.foo setValue:1.0
     ^~~~
1 warning generated.

Only one warning even though the get and set tests are the same — just calling XCTFail() in a success block.

Jenkins Clang Scan-Build Plugin: Support Matrix Builds

| comments

I’m using Jenkins to build iOS projects (as you may have noticed from my previous jenkins posts). One of build steps that can help developers is running the Clang scan-build static analyzer and publishing the results. Luckily, there is an existing Clang Scan-Build Jenkins plugin available, however it hasn’t been updated for a while. I stumbled upon Sean Wang’s blog post (https://fclef.wordpress.com/2014/10/11/jenkins-clang-scan-build-plugin-support-for-xcode5-and-later/) describing his fixes for latest Xcode. That’s a great update!

So it worked fine until I needed to use it in a matrix (aka multi-configuration) project. It was missing from the list of available build steps! One solution is to emulate the matrix build by having N regular builds, one for each of the configurations, to run the analyzer, but that would be very painful to maintain.

Jenkins Doesn’t Run as a LaunchAgent?

| comments

If you are interested in Jenkins and followed my post about setting it up in a virtual machine, you should be totally fine. However, when I was messing with it, I had an issue when the jenkins agent wouldn’t start:

1
2
3
launchctl load ~/Library/LaunchAgents/org.jenkins-ci.plist
launchctl load ~/Library/LaunchAgents/org.jenkins-ci.plist
/Users/Shared/Jenkins/Library/LaunchAgents/org.jenkins-ci.plist: Operation already in progress

Jenkins: Admin Is Missing the Overall/Read Permission

| comments

I stumbled upon this issue recently: somebody has created an admin user in a fresh Jenkins installation (most likely, through the normal Jenkins interface). However, after a few days, they couldn’t login as the admin, seeing this error:

admin is missing the Overall/Read permission