JIRA Pre-Upgrade check – call for votes

Let’s start with a bottom line: if you’re a JIRA user, please take a few seconds to vote for the ‘JIRA Pre-Upgrade check’ suggestion

Now for the whole story:

Recently we upgraded one of our JIRA instances. It all seems well at first and then small problems started to pile up.

After contacting Atlassian support, it turns out we should have upgraded our database server (Oracle in this case) before the upgrade (“it’s in the documentation!”). We didn’t, so some data upgrade tasks silently failed, without any notification during or after the upgrade process.

I was surprised. As a long-time installation developer I learned one thing: users don’t read the documentation until they have problems. They certainly don’t read installation guides; at most they skim through the release notes. That’s why every installation I create includes some basic validations regarding the environment (e.g. OS, database, Java…).

So, I suggested Atlassian to add this kind of checks to their own installer and they immediately agreed. All that’s left is to gather enough votes so it would go into their suggestion review process. Appreciate your help!

Advertisements

JIRA Tip: issues showing on Kanban board but missing on Scrum board

Let’s say you have two JIRA projects, project K using a Kanban board and project S using a Scrum board. Each project with its own set of statuses and workflows.

Now, users of project S want to see issues from project K on their Scrum board. They update the board filter accordingly, but to their surprise, many project K issues are not  visible in the Backlog.

Why? because a JIRA board (either Scrum or Kanban) only shows issues whose statuses are mapped to the board’s columns (e.g. To Do, In Progress, Done).
Issues with unmapped status are not displayed on the board at all. This is useful in some scenarios but confusing in others, such as in the example above.

To remedy the situation, go to the Scrum board’s configuration, and under the ‘Columns’ sections you can map or unmap statuses as you see fit.

Quick tip: Using Python’s expandvars() with quoted variables on Windows

I recently encountered an elusive bug, which eventually I tracked down to the fact that environment variables are not replaced in a certain string even though it is set by calling os.path.expandvars(original string).

Turns out, the problem is that expandvars() doesn’t expand variables who are enclosed within a string literal. I couldn’t find it documented anywhere but facts are, this is the case.

Small example:

>>> import os
>>> os.environ['VAR1'] = 'Value1'
>>> s1 = "this is '%VAR1%'"
>>> os.path.expandvars(s1)
"this is '%VAR1%'"
>>> s2 = "this is %VAR1%"
>>> os.path.expandvars(s2)
'this is Value1'

It may be a good idea in some cases, but for me it was quite an annoyance.

So, how to overcome this?

Continue reading

Running Python Unit Test in a VSTS/TFS build

Here’s a short explanation how to execute python unit tests during VSTS/TFS builds, without the need of plug-ins. The basic idea is to create a JUnit XML from your test results, and then have it published to the TFS build dashboard.

First, on the relevant build agent(s), install the pytest module. You can use the following command, or your favorite CM tool.

python -m pip install pytest

Next, edit your build definition in TFS, and add two build steps: one (Batch Script) for running py.test to generate a junit XML, and one (Publish Test Results) for publishing the xml to the test results page.
The full command line to run the tests is as follows (in this example, the unittest code is in test_MyApp.py):

python -m py.test --junitxml test-results.xml test_MyApp.py

Here is a sample build definition which includes only those two steps:

BuildSteps

Build Steps

BatchScript

Batch Script Settings

 

Finally, queue the build, and you will able to see the test results in the build page:

TestResults

 

 

InstallShield: Where is the ‘Create New Folder’ button when browsing?

InstallShield users may have noticed that, in all the ‘select folder’ type dialogs, there is no ‘Create New Folder’ button. If the user wants to create one, he can only do it from Windows itself, or (in some dialogs) type it as text. This is because all these dialogs call the SelectDir() function when clicking Browse.

This is of course very inconvenient, I saw several uses complain about it, but the situation remains.

I came up with a solution, inspired by this KB Article (how to browse for files in InstallScript). Basically I created my own version of AskDestPath() dialog, and modified the behavior so when clicking Browse it will call a custom function i wrote, based on Windows API SHBrowseForFolder().

You can find the custom function on my GitHub here.

The only issue I have is that I cannot set the initial folder. This is a known drawback of this specific API function, and there is a known C++ workaround – but it cannot apply to InstallShield since it does not support pointers to functions (it crashes if you try).

ClearCase Windows Quick Tip: Find all symbolic links

Our ClearCase repository make heavy use of ClearCase symbolic links. We began an initiative to get rid of them, since they cause lots of problems – from snapshot view size, to tools not supporting them (e.g. WebPack), and Git migration efforts. See also my previous post on this matter.

The first step, of course, is to find all of them. One may think that cleartool find command will provide this functionality, but it’s lackcing. So we came up with this simple command-line:

cleartool ls -l -r <folder> | findstr /C:"symbolic link"

Folder must be a VOB, or a folder inside a VOB. To iterate on all VOBs, you can run:

for /d %i in (<view root>\*) do @cleartool ls -l -r %i | findstr /C:"symbolic link"

Now, we just need to figure out what to do with all of them…

InstallShield scripting: Create a list of distinct items from a given list

Recently I had a situation when I needed the ability to take a list of strings and eliminate duplicates.

Now, in all modern languages, this is a built-in capability or data structure – set() in Python, Distinct() in C#,  etc.

But InstallScript is too basic for that. Since we need dynamic arrays, all we have to work with is the LIST object. So, after some trial and error, I came up with this piece of code, which is quite efficient; the only downside is that the order of items is not kept – but in my case it didn’t matter.

Continue reading