VSTS/Azure DevOps: Auto-Increment NuGet Package Version on Pack - .net-core

Running the .NET Core Pack task, how do I get the outputted NuGet package version to auto-increment itself?
So, for example, if my current version is 1.0.0, then the next time I call the Pack task, I would like to see 1.0.1.
I'm using environment build variables with Build.BuildNumber and getting outputs at the moment of e.g. 20180913-.2.0, etc. I would like to establish to a more traditional versioning system.

From the docs, the variable Rev:.r is the daily build revision count. The accepted "solution" would lead to one day finishing having a version of 1.0.12, then the next day it will be 1.0.1.
If you want a simple incremental and unique semver, use 1.0.$(BuildID).
$(BuildID) is an internal immutable counter for your builds, and thus far cleaner than $(BuildNumber).
BuildID will always be incrementing - no reset.
Thus after a minor bump, you'd end up having say 1.2.123 becoming 1.3.124.
If you want to perform this task well, this can be done using npm version or similar, such as pubspec_version for Dart or Flutter builds.
- script: npm version $RELEASE_TYPE
where $RELEASE_TYPE is a variable you can set based on build (ie: CI, PR etc), having a value of major, minor, patch, prerelease etc.
- script: npm version $RELEASE_TYPE
condition: startsWith(variables['build.sourceBranch'], 'refs/head/release/')
env:
releaseType: minor
Update: Bump Repo Version and Use In Build (using npm)
To have the repo version update, I ended up including npm version as a DevDependency, with it's precommit hook to bump the project version on any commit.
This technique can be applied to other project types, placing them in a subfolder - although can lead to complications with server OS requirements.
To use this version in your build, add this bash script task, which gets and exports the version as a task variable:
v=`node -p "const p = require('./package.json'); p.version;"`
echo "##vso[task.setvariable variable=packageVersion]$v"
.Net Core Task only version
Unfortunately, no repo-bump.
Workaround 1:
jobs:
- job: versionJob #reads version number from the source file
steps:
- powershell: |
$fv = Get-Content versionFile
Write-Host ("##vso[task.setvariable variable=versionFromFile;isOutput=true]$fv")
displayName: 'version from file'
name: setVersionStep
- job: buildJob # consumes version number, calculates incremental number and set version using assemblyinfo.cs
dependsOn: versionJob
variables:
versionFromFile: $[ dependencies.versionJob.outputs['setVersionStep.versionFromFile'] ] # please note that spaces required between $[ and dependencies
buildIncrementalNumber: $[ counter(dependencies.versionJob.outputs['setVersionStep.versionFromFile'],1) ] #can't use $versionFromFile here
steps:
- powershell: |
Write-Host ($env:versionFromFile)
Write-Host ($env:versionFromFile + '.' + $env:buildIncrementalNumber)
displayName: 'version from file output'
Workaround 2:
This post describes a couple of others, using version-prefix and automatically applying the BuildNumber as a version-suffix.

I may have figured it out. For anyone tearing their hair out, try this:
Pack Task:
Automatic Package Versioning: Use an environment variable
Environment variable: Build.BuildNumber
Then, up in the top menu where you have Tasks, Variables, Triggers, Options, click Options and set:
Build number format: 1.0$(Rev:.r)
Save and queue. This will produce e.g. 1.0.1.
(Please Correct me if I am wrong, or if this does not work long-term.)

If you're just looking to bump the major, minor or revision version number, using counter operator in a variable is a simple and elegant approach. It will automatically add one to the current value.
Here's what I use:
variables:
major: '1'
minor: '0'
revision: $[counter(variables['minor'], 1)] #this will get reset when minor gets bumped. The number after Counter is the seed number (in my case, I started at 1).
app_version: '$(major).$(minor).$(revision)'
If you would like to see a real-world 4-job pipeline that uses this, I have one here https://github.com/LanceMcCarthy/DevReachCompanion/blob/master/azure-pipelines.yml

For me it's enough to set Build number format on Options tab to
$(date:yyyy).$(date:MMdd)$(rev:.r)
and add next build argument:
/p:Version=1.$(Build.BuildNumber) /p:AssemblyVersion=1.$(Build.BuildNumber)
In this case we manage major version manually, but minor version and build number will be set automatically. Easy to understand what version you have deployed.

I am using the ado pipeline and a yaml build. What I've done is utilized the pipeline variables, a counter function, and an inline powershell function to create the version number. It auto-increments and has made the entire build process nice.
Another SO Post about something similar

Related

Concourse CI and Build number

I'm moving from Jenkins to using using Concourse CI to run my Sauce labs e2e tests. Sauce labs groups tests together that have the same build number string:
name: 'Chrome XS',
browserName: 'chrome',
tunnelIdentifier: process.env.TUNNEL_IDENTIFIER,
build: process.env.JENKINS_BUILD_NUMBER,
platform: 'Windows 10',
shardTestFiles: true,
maxInstances: 20,
How can I pass the build number to my script using an environment variable as shown above. The Concourse GUI uses name #number. Is there any way to retrieve this. I tried printing all the environment variables in the docker container but it's not set by default.
Metadata like the build number/ID are intentionally not provided to tasks. See https://concourse-ci.org/implementing-resources.html#resource-metadata
This sounds like potentially a use case for a Sauce Labs resource?
In Concourse, build metadata is only available for resources, not tasks.
An example on using build metadata with resources is to include it as part of build results notification emails. The following blog entry contains more information about it:
http://lmpsilva.typepad.com/cilounge/2016/10/how-to-insert-build-metadata-into-user-notifications-in-concourse.html
If you really want to use build number for versioning, you could try to create your own Concourse resource that would return the version number, however, I would use your code commit number instead. Another alternative would be to use the Semver resource in Concourse: https://github.com/concourse/semver-resource

What does it mean: WARNING! Excluded dependencies (not part of the Hex package)?

When I try to publish a new version of my package on hex, it prints the following warning:
WARNING! Excluded dependencies (not part of the Hex package):
ex_doc
Full text of me running the command:
$ mix hex.publish
Publishing usefulness 0.0.5
Dependencies:
earmark >= 0.0.0
Files:
lib/usefulness.ex
lib/usefulness/stream.ex
lib/usefulness/string.ex
config/config.exs
test/test_helper.exs
test/usefulness_test.exs
mix.exs
README.md
LICENSE
App: usefulness
Name: usefulness
Description: Useful things
Version: 0.0.5
Build tools: mix
Licenses: Apache 2.0
Maintainers: afasdasd
Links:
Github: https://github.com/b-filip/usefulness
Elixir: ~> 1.2
WARNING! Excluded dependencies (not part of the Hex package):
ex_doc
Before publishing, please read Hex Code of Conduct: https://hex.pm/docs/codeofconduct
Proceed? [Yn]
I have no idea what this warning means
Here is what my project.deps in mix.exs consists of:
defp deps do
[
{:ex_doc, "~> 0.11", only: :dev},
{:earmark, ">= 0.0.0"}
]
end
It means you have a dependency in your project that will not be a dependency of your package that you publish to hex. This is normal, projects often have development dependencies for testing, static analysis, generating documentation etc.
Hex lists them so you can have a quick look and make sure you didn't leave out an actual dependency of your code, that would result in a broken package.
ExDoc should most likely not be a dependency of your package. You're good to go. Good work creating your hex package!

How to skip a specific migration with flyway?

I'm using flyway with gradle, I've run one of the migrations manually inside the database console, I want to run flyway, but tell it to ignore one specific migration version in between all the others.
Can this be done?
You would have to hack it a bit to get it to work, so I don't recommend this approach, but it would work in a pinch.
I've only tested this with Maven, but I'm pretty sure it'd work with Gradle too.
Migrate up until the version before the one you applied manually
# Assuming you applied 01.002 manually
$ mvn flyway:migrate -Dflyway.target=01.001
Insert a row for the script you applied
-- Make sure these vals closely replicate those from other rows
insert into schema_version( installed_rank, version, description, type, script, checksum, installed_by, installed_on, execution_time, success)
values ( 2, '01.002', 'static_data', 'SQL', 'V01/V01.002__static_data.sql', null, 'username', current_timestamp, 0, true );
Repair the schema_version checksum
$ mvn flyway:repair
Apply the other migrations
$ mvn flyway:migrate -Dflyway.validateOnMigrate=false -Dflyway.outOfOrder=true
The two -D properties there may not be necessary, depending on whether you got the insert correct or not. Flyway may disagree with your script description, for example, even if the checksum is now correct.
Not Recommended, but if you still want to:
Run flywayMigrate, let the migration fail.
Manually, update the flyway meta table (success column) for that specific version of migration.
Run flywayMigrate again.
Done, flyway will now start with the next version of migration.
As of version 7, you can add it directly to your Maven or Grade file
Gradle - Skip
flyway {
skipExecutingMigrations = true
}
Maven - Skip
<configuration>
<skipExecutingMigrations>true</skipExecutingMigrations>
</configuration>
Documentation Reference Skip
Gradle - Cherry Pick
flyway {
cherryPick = '2.0'
}
Maven - Cherry Pick
<configuration>
<cherryPick>2.0</cherryPick>
</configuration>
Documentation Reference Cherry Pick

Defining plugin dependency between subprojects in SBT?

EDIT:
Since I put up the bounty, I thought I should restate the question
How can a SBT project P, with two sub-projects A and B, set up B to have a plugin dependency on A, which is a SBT plugin?
Giving P a plugin dependency on A does not work, since A depends on other things in P, which results in a circular dependency graph
It has to be a plugin dependency, for A is a plugin needed to run Bs test suite.
dependsOn doesn't work, because, well, it has to be a plugin dependency
I'd like to know either of
How to do this, or
Why this is impossible, and what the next best alternatives are.
EDIT: clarified that it's a plugin-dependency, since build-dependency is ambiguous
When you have a multi-project build configuration with "project P and two sub-projects A and B" it boils down to the following configuration:
build.sbt
lazy val A, B = project
As per design, "If a project is not defined for the root directory in the build, sbt creates a default one that aggregates all other projects in the build." It means that you will have an implicit root project, say P (but the name is arbitrary):
[plugin-project-and-another]> projects
[info] In file:/Users/jacek/sandbox/so/plugin-project-and-another/
[info] A
[info] B
[info] * plugin-project-and-another
That gives us the expected project structure. On to defining plugin dependency between B and A.
The only way to define a plugin in a SBT project is to use project directory that's the plugins project's build definition - "A plugin definition is a project in <main-project>/project/." It means that the only way to define a plugin dependency on the project A is to use the following:
project/plugins.sbt
addSbtPlugin("org.example" % "example-plugin" % "1.0")
lazy val plugins = project in file(".") dependsOn(file("../A"))
In this build configuration, the plugins project depends on another SBT project that happens to be our A that's in turn a plugin project.
A/build.sbt
// http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin
sbtPlugin := true
name := "example-plugin"
organization := "org.example"
version := "1.0"
A/MyPlugin.scala
import sbt._
object MyPlugin extends Plugin
{
// configuration points, like the built in `version`, `libraryDependencies`, or `compile`
// by implementing Plugin, these are automatically imported in a user's `build.sbt`
val newTask = taskKey[Unit]("A new task.")
val newSetting = settingKey[String]("A new setting.")
// a group of settings ready to be added to a Project
// to automatically add them, do
val newSettings = Seq(
newSetting := "Hello from plugin",
newTask := println(newSetting.value)
)
// alternatively, by overriding `settings`, they could be automatically added to a Project
// override val settings = Seq(...)
}
The two files - build.sbt and MyPlugin.scala in the directory A - make up the plugin project.
The only missing piece is to define the plugin A's settings for the project B.
B/build.sbt
MyPlugin.newSettings
That's pretty much it what you can do in SBT. If you want to have multi-project build configuration and have a plugin dependency between (sub)projects, you don't have much choice other than what described above.
With that said, let's see if the plugin from the project A is accessible.
[plugin-project-and-another]> newTask
Hello from plugin
[success] Total time: 0 s, completed Feb 13, 2014 2:29:31 AM
[plugin-project-and-another]> B/newTask
Hello from plugin
[success] Total time: 0 s, completed Feb 13, 2014 2:29:36 AM
[plugin-project-and-another]> A/newTask
[error] No such setting/task
[error] A/newTask
[error] ^
As you may have noticed, newTask (that comes from the plugin from the project A) is available in the (default) root project and the project B, but not in A.
As Jacek said, it cannot be done as I would like, as a subproject cannot have a SBT plugin that the root project does not. On the other hand, this discussion on the mailing list contains several alternatives, and would no doubt be useful to anyone who comes across this question in the future.
EDIT: Well, in the end the alternatives mentioned (sbt scripted, etc) were hard and clunky to use. My final solution was to just have a separate project (not subproject) inside the repo that depends on the original project via it's ivy coordinates, and using bash to publishLocal the first project, going into the second project and running its tests
sbt publishLocal; cd test; sbt test; cd ..
I always thought the point of something like SBT was to avoid doing this kind of bash gymnastics, but desperate times call for desperate measures...
This answer may include the solution https://stackoverflow.com/a/12754868/3189923 .
From that link, in short, set exportJars := true and to obtain jar file paths for a (sub)project exportedProducts in Compile.
Leaving the facts about plugins by side, you have a parent project P with sub-projects A and B. And then you state that A depends on P. But P is a aggregate of A and B and hence depends on A. So you already have a circular dependency between A and P. This can never work.
You have to split P in two parts: The part where A depends on (let's call this part A') and the rest (let's call this P_rest). Then you throw away P and make a new project P_rest consisting of A', A and B. And A depends on A'.

Version information on Xserver modules

I am trying to find a tool that will extract the module version information (a part of the module record) fron an Xserver module. For example, in the Xorg logs I can see the following information for the librecord module in my Xorg.0.log file...
[ 39.892] (II) Loading /usr/lib/xorg/modules/extensions/librecord.so
[ 39.905] (II) Module record: vendor="X.Org Foundation"
[ 39.905] compiled for 1.9.0, module version = 1.13.0
[ 39.905] Module class: X.Org Server Extension
[ 39.905] ABI class: X.Org Server Extension, version 4.0
Is there a tools that would allow me to easily extract the aforementioned information. Sometimes you can use modinfo on the module and that will have version information, but that does not always work. The only consistent way I know of now is to parse the xorg log file. Thanks.
Yes, there is and you can also try to write a small one.
http://gitorious.org/xdriverprobe
The problem is that xdriverprobe won't compile on newer servers since I didn't update it to the newest ABIs. Also, xdriverprobe is only used for video drivers, but it can be adapted to be used on other modules. The main source code file (xdriverprobe.c) has less than 500 lines, so you can easily learn by reading it.
It works in Ubuntu 11.10... ./xdriverprobe -o moduledata gives the information you want.
Look at its source code. It does:
dlopen() the module
find a symbol called modulenameModuleData (if your module is called modulename)
that symbol is a XF86ModuleData* See /usr/include/xorg/xf86Module.h
check its member named vers
Spend a few hours and you'll be able to write a very tiny code that does what you want.
More information: http://www.xfree86.org/current/DESIGN17.html#65 (very old document, but most of what's written there is still true today). If you're not happy with that document, you have to read the Xorg source code.
Happy hacking!

Resources