how to parse package.json version for github "gh release" tag? - github

I want to create a single command that would do following:
increase the package.json version (I could do this by running npm version patch)
create Github release with that version as tag (not sure how to achieve this step?)
Brownie points if I could supply patch/minor/major flag while running the command so that npm version _flag_ runs instead of always patching.
I'm using gh package https://cli.github.com/manual/gh_release_create

To get the version node -pe "require('./package.json').version"
A script with optional argument as asked, if no args this will do a patch.
Then launch interactive release creation with the new version
#!/bin/sh
if [ $# -eq 0 ]
then
action="patch"
else
case $1 in
minor | major | patch)
action=$1
;;
*)
echo "Unknow $1 command"
return -1
;;
esac
fi
npm version $action
version=`node -pe "require('./package.json').version"`
echo "new version $version"
gh release create $version

Related

add a variable to yocto SDK environment setup script

How to add a environment variable to yocto SDK environment setup script.
export CODE_ARGS = "${SAMPLE_ARGS}"
I want to add this CODE to SDK environment setup script.
These steps might depend on which Yocto release you are using, but the general idea should be the same.
Steps for Yocto kirkstone:
Looking at the end of the environment setup script you should see something like
# Append environment subscripts
if [ -d "$OECORE_TARGET_SYSROOT/environment-setup.d" ]; then
for envfile in $OECORE_TARGET_SYSROOT/environment-setup.d/*.sh; do
. $envfile
done
fi
if [ -d "$OECORE_NATIVE_SYSROOT/environment-setup.d" ]; then
for envfile in $OECORE_NATIVE_SYSROOT/environment-setup.d/*.sh; do
. $envfile
done
fi
and e.g. openssl recipe leverages this functionality:
do_install:append:class-nativesdk () {
mkdir -p ${D}${SDKPATHNATIVE}/environment-setup.d
install -m 644 ${WORKDIR}/environment.d-openssl.sh ${D}${SDKPATHNATIVE}/environment-setup.d/openssl.sh
sed 's|/usr/lib/ssl/|/usr/lib/ssl-3/|g' -i ${D}${SDKPATHNATIVE}/environment-setup.d/openssl.sh
}
So install shell scripts either under SDKPATHNATIVE or SDKPATH depending if the variable is used for all targets (SDKPATHNATIVE) or for a single target (SDKPATH)

cpack restrict OS version package can be installed on

I create packages for several OS versions including RHEL7 & RHEL8 (or mostly equally CentOS7 & 8).
It is possible to install a package built for .el7. on .el8. but it will typically not work (for example due to undefined symbols etc).
Ideally I would like to make the installation fail with an error message like "this package is only intend for RHEL7/CentOS7".
How can I do this?
More specifically how can I do this with CPack/CMake?
Bonus points if you can also given an explanation suitable for Debian versions.
Here are some ideas I have so far:
Use dist tags somehow, see:
https://serverfault.com/questions/283330/rpm-spec-conditional-require-based-of-distro-version
Check uname -r at install time in a pre-install script
Part of that answer is here:
How to check os version in rpmbuild spec file
https://unix.stackexchange.com/questions/9296/how-can-i-specify-os-conditional-build-requirements-in-an-rpm-spec-file
I'm not quite sure how to do that using cpack. I do not want to generate a custom spec file as the build machinery is already complex enough.
Another option would be to add a %requires on a package that only exists on RHEL7 but not RHEL8 or visa versa. That package would need to also exist on CentOS and not change in a way that would make the installation fail if it is upgraded. Does anyone know a suitable package to depend on?
For example:
>rpm -q --whatprovides /etc/redhat-release
centos-release-8.2-2.2004.0.1.el8.x86_64
This looks like a good candidate but if I add a dependency on centos-release-8.2 and they later upgrade to centos-release-8.3 or use RedHat instead this will not work.
I did this before by having a stanza in %pre that stopped it:
if [ -n "%{dist}" ]; then
PKG_VER=`echo %{dist} | perl -ne '/el(\d)/ && print $1'`
THIS_VER=`perl -ne '/release (\d)/ && print $1' /etc/redhat-release`
if [ -n "${PKG_VER}" -a -n "${THIS_VER}" ]; then
if [ ${PKG_VER} -ne ${THIS_VER} ]; then
for i in `seq 20`; do echo ""; done
echo "WARNING: This RPM is for CentOS${PKG_VER}, but you seem to be running CentOS${THIS_VER}" >&2
echo "You might want to uninstall these RPMs immediately and get the CentOS${THIS_VER} version." >&2
for i in `seq 5`; do echo "" >&2; done
fi
fi
fi
Remember - you cannot have any user interaction in RPM installation. You could have it fail instead of warn tho; that's up to you.

Visual Studio Online automatic build version number increment and assembly patching

i am using for a long time TeamCity.
The AssemblyInfo patcher has the ability to patch all assemblyinfo files with a version number that is generated and incremented by TeamCity.
Is this somehow possible with Visual Studio Online Build (the new scriptable, cross-platform one)?
I've created a Bash Script which automatically replaces the version number in files such as AssemblyVersion.cs and can be used in a build-step, similar to the Power Shell Script published by Microsoft:
#!/bin/bash
# Sample call: ./ApplyVersionToAssemblies.sh ../Source/ AssemblyInfo.cs XamarinAndroid_1.0.0.1
echo "Script to automatically set the version-number in files (e.g. AssemblyInfo.cs)"
if [ $# -ne 3 ]; then
echo "Usage: $0 path_to_search filename build_number"
exit
fi
# Input is something like XamarinAndroid_1.2.3.4 and we want to extract only the 1.2.3.4
# See http://stackoverflow.com/a/19482947/448357 for more infos
VERSION_NUMBER="${3#*_}"
for file in $(find $1 -name $2); do
echo "Replacing Version string in $file with ${VERSION_NUMBER}"
sed -i '' -e 's/"[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*"/"'${VERSION_NUMBER}'"/' "$file"
done
First, create variables for Major and Minor version
Second, set the build-number format to $(BuildDefinitionName)_$(Major).$(Minor).$(Year:yy)$(DayOfYear).$(Rev:rr) in the General tab of your build definition
And finally create a bash-script or a Powershell step with the scripts from above:

Including some SFTP commands in a Makefile

I use a Makefile to create pdfs of papers I'm working on. I'd also like to use make to upload the latest version to my website, which requires sftp. I though I could do something like this (which words on the command line) but it seems that in make, the EOF is getting ignored i.e., this
website:
sftp -oPort=2222 me#mywebsite.com << EOF
cd papers
put research_paper.pdf
EOF
generates an error message
cd papers
/bin/sh: line 0: cd: papers: No such file or directory
which I think is saying "papers" doesn't exist on your local machine i.e., the 'cd' is being executed locally, not remotely.
Couple of ideas:
use ncftp which every Linux distro as well as brew should have: it remembers 'state' so the cd becomes unnecessary
use scp instead of sftp if possible
write a trivial shell script doing the EOF business and call that
For what it is worth, here is my script to push tarballs to the CRAN winbuilder -- and takes target directory and script as arguments to ncftpput.
#!/bin/bash
function errorexit () {
echo "Error: $1"
exit 1
}
if [ "$#" -lt 1 ]; then
errorexit "Need to specify argument file"
fi
if [ ! -f ${1} ]; then
errorexit "File ${1} not found, aborting."
fi
ncftpput win-builder.r-project.org /R-release ${1}
ncftpput win-builder.r-project.org /R-devel ${1}
I then just do wbput.sh foo_1.2-3.tar.gz and off it goes...
You cannot (normally) put a single command on multiple lines in a Make recipe, so here documents are a no-go. Try this instead:
website: research_paper.pdf
printf 'cd papers\nput $<\n' \
| sftp -oPort=2222 me#mywebsite.com
The target obviously depends on the PDF, so I made it an explicit dependency, as well.

GitHub URL for latest release of the _download file_?

Although this question is similar to GitHub latest release, it's actually different -- it's about a link that means "the latest version of the download file itself".
GitHub provides a "Latest" URL that redirects to the information page for the latest release. For example: https://github.com/reactiveui/ReactiveUI/releases/latest will redirect to https://github.com/reactiveui/ReactiveUI/releases/tag/5.99.6 (as I type this; or to the page for a newer version, someday).
That's great but I need a URL to the download file itself. In this example, the .zip file associated with the green download button, https://github.com/reactiveui/ReactiveUI/releases/download/5.99.6/ReactiveUI-5.99.6.zip (as I type this; or to a newer zip file, someday).
Why? I want to give the URL to curl, as part of a Travis CI script, to download the latest version.
I guessed at a few URLs like /releases/download/latest/file.zip (substituting "latest" for the version part) and /releases/download/file.zip but those 404.
Is there any way to do this -- in the context of a shell script and curl (note: not in a browser page with JS)?
For releases that do not contain the version number or other variable content in their assets' names, you can use a URL of the format:
https://github.com/owner/repository/releases/latest/download/ASSET.ext
As per the docs:
If you'd like to link directly to a download of your latest release asset you can link to /owner/name/releases/latest/download/asset-name.zip.
Here is a way to do it w/o Github if you have a single download in the release:
wget $(curl -s https://api.github.com/repos/USERNAME/REPONAME/releases/latest | grep 'browser_' | cut -d\" -f4)
It is pretty easy (though not pretty), and of course you can swap out wget for another curl call if you want to pipe it to something.
Basically, the curl call nets you a JSON structure, and I'm just using basic shell utilities to extract the URL to the download.
Very interesting, I haven't noticed a "latest" tag in GitHub-releases yet. As i now figured out, they're given away if you're using the "pre-release"-capabilities of GitHubs release-system. But i don't know any way to access binaries via a latest-path.
I would like to suggest you using git (which is available in your travis-vm) to download the latest tag.
Like Julien Renault describes in his blog post, you will be able to checkout the latest tag in the repository like this:
# this step should be optional
git fetch --tags
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
git checkout $latestTag
This solution is based on the assumption that the latest tag is also the latest version.
I use this to get the download URLs in PowerShell 5+ (replace ACCOUNT & REPO)
Invoke-RestMethod -uri https://api.github.com/repos/ACCOUNT/REPO/releases/latest | select -ExpandProperty assets | select -expand browser_download_url
Note if they have more than one package this will be a list. If you want to pick a certain one find a unique part of the name i.e. win for Windows and use:
(replace ACCOUNT, REPO & SELECTOR)
Invoke-RestMethod -uri https://api.github.com/repos/ACCOUNT/REPO/releases/latest | select -ExpandProperty assets | ? { $_.name.Contains("SELECTOR")} | select -expand browser_download_url
As a bonus if you assign the above to a variable you can then grab the file and extract it with the following (assuming you assign to $uri):
Invoke-WebRequest $uri -OutFile "release.zip"
Expand-Archive .\release.zip
In PowerShell 6+ this should work on other platforms than Windows.
On windows, only using powershell, this works for me. It can probably be written a lot shorter.
#Downloads latest paket.bootstrapper.exe from github
$urlbase = "https://github.com"
$latestPage="$urlbase/fsprojects/Paket/releases/latest"
Write-Host "Parsing latest release page: $latestPage"
$page=Invoke-Webrequest -uri $latestPage
$latestBootStrapper=($page.Links | Where-Object { $_.href -match "bootstrapper" }).href
$dlurl="$urlbase$latestBootStrapper"
Write-Host "Downloading paket.bootstrapper.exe from $dlurl"
$wc=new-object net.webclient
$wc.UseDefaultCredentials=$true
$wc.Proxy.Credentials=$wc.Credentials
$wc.DownloadFile($dlurl, (join-path (resolve-path ".\") "paket.bootstrapper.exe"))
$repoName = "PowerShell/PowerShell"
$assetPattern = "*-win-x64.msi"
$extractDirectory = "C:\Users\Public\Downloads"
$releasesUri = "https://api.github.com/repos/$repoName/releases/latest"
$asset = (Invoke-WebRequest $releasesUri | ConvertFrom-Json).assets | Where-Object name -like $assetPattern
$downloadUri = $asset.browser_download_url
$extractPath = [System.IO.Path]::Combine($extractDirectory, $asset.name)
Invoke-WebRequest -Uri $downloadUri -Out $extractPath
You can use curl with https://api.github.com. It gives JSON output from which you can easily extract what you need with jq or your favorite json tool.
For example, using the repository in the question:
gituser=reactiveui; repo=ReactiveUI
tag_name=$(curl -sL https://api.github.com/repos/$gituser/$repo/releases/latest | jq -r '.tag_name'); echo $tag_name
# output: "16.3.10"
tarurl=$(curl -sL https://api.github.com/repos/$gituser/$repo/releases/latest | jq -r '.tarball_url'); echo $tarurl
# output: https://api.github.com/repos/reactiveui/ReactiveUI/tarball/16.3.10
zipurl=$(curl -sL https://api.github.com/repos/$gituser/$repo/releases/latest | jq -r '.zipball_url'); echo $zipurl
# output: https://api.github.com/repos/reactiveui/ReactiveUI/zipball/16.3.10
So you could get the download with a nested curl in a one-liner:
curl -OL $(curl -sL https://api.github.com/repos/filesender/filesender/releases/latest | jq -r '.tarball_url')
This will download the file, and save it with the name of its tag_name, but without extension. So you may want to rename it by appending ".tgz" or ".zip", depending on which you downloaded.
Note for Windows users: curl is now installed by default on Windows too, but beware that it must be called as curl.exe. That's because Powershell has an alias stupidly called "curl" which is not the same!
Centos/RHEL
There are 2 options to download using the URL directly.
Via Github API (using CURL and jq package)
Via Github direct (using CURL and sed)
I am listing a demonstration script for each option.
Option 1
#!/bin/bash
# author: fullarray
# Contribution shared on: stackoverflow
# Contribution shared on: github
# date: 06112022
compose_version=$(curl https://api.github.com/repos/docker/compose/releases/latest | jq .name -r)
get_local_os_build=$(uname -s)-$(uname -m)
curl -L https://github.com/docker/compose/releases/download/$compose_version/docker-compose-$get_local_os_build
Option 2
#!/bin/bash
# author: fullarray
# Contribution shared on: stackoverflow
# Contribution shared on: github
# date: 06112022
get_local_os_build=$(uname -s)-$(uname -m)
compose_latest_version=$(curl -L "https://github.com/docker/compose/releases/download/`curl -fsSLI -o /dev/null -w %{url_effective} https://github.com/docker/compose/releases/latest | sed 's#.*tag/##g' && echo`/docker-compose-$get_local_os_build")
If you are fine with cloning the repository first, you can use git tag, which also allows you to sort the tags by version in various ways.
git clone https://github.com/reactiveui/ReactiveUI.git .
LATEST="$(git tag --sort=v:refname | tail -n1)"
git checkout "$LATEST"
This allows for more flexibility, as you can filter the tags you're not interested in with grep, e.g.:
git tag --sort=v:refname | grep -vE '-RC[0-9]+$' | tail -n1
Here's an excerpt from the documentation on git-tag:
Sort based on the key given. Prefix - to sort in descending order of the value. You may use the --sort=<key> option multiple times, in which case the last key becomes the primary key. Also supports version:refname or v:refname (tag names are treated as versions). The version:refname sort order can also be affected by the versionsort.suffix configuration variable. The keys supported are the same as those in git for-each-ref. Sort order defaults to the value configured for the tag.sort variable if it exists, or lexicographic order otherwise. See git-config(1).
If you really don't want to clone the repository, the --sort option also works with git ls-remote. It'll just take a bit more work to get the part you're interested in:
git ls-remote --tags --sort=v:refname https://github.com/reactiveui/ReactiveUI.git | awk -F'/' '{ print $NF }'
This approach doesn't seem to work all too well for the ReactiveUI repository in particular, because their tags are a bit messy, but it's an option.
Please note, that the sorting isn't quite the same as with semantic versioning, but git does allow you to work around most of these cases. As an example mqtt2prometheus has release candidates using the suffix RC1, RC2 etc., but git sorts 0.1.6-RC1 as being newer than 0.1.6. You can tell git that "RC" is a pre-release suffix to make it sort them correctly.
git tag -c 'versionsort.suffix=-RC' --sort=v:refname | tail -n1
Here's an excerpt from the documentation on git-config:
By specifying a single suffix in this variable, any tagname containing that suffix will appear before the corresponding main release. E.g. if the variable is set to "-rc", then all "1.0-rcX" tags will appear before "1.0". If specified multiple times, once per suffix, then the order of suffixes in the configuration will determine the sorting order of tagnames with those suffixes. E.g. if "-pre" appears before "-rc" in the configuration, then all "1.0-preX" tags will be listed before any "1.0-rcX" tags.
You can also sort by the date of the tag using --sort=taggerdate, that might work better in some situations.
As #florianb pointed out, I should use git.
Originally my .travis.yml was something like:
before_install:
- curl -L https://raw.githubusercontent.com/greghendershott/travis-racket/master/install-racket.sh | bash
This would automatically get whatever the latest version is, from the repo.
But someone pointed out to me that GitHub doesn't want people to use raw.github.com for downloads. Instead people should use "releases". So I was a good doob and manually made a release each time. Then my .travis.yml was something like:
before_install:
- curl -L https://github.com/greghendershott/travis-racket/releases/download/v0.6/install-racket.sh | bash
But it's a PITA to make a release each time. Worse, all .travis.yml files need to be updated to point to the newer version of the file.
Instead -- just use git to clone the repo, and use the file within it:
before_install:
- git clone https://github.com/greghendershott/travis-racket.git
- cat travis-racket/install-racket.sh | bash # pipe to bash not sh!