How to test project's CMake minimum with GitHub actions? - cmake

cmake_minimum_required(VERSION 3.X.Y) does not guarantee your CMake will work with CMake 3.X.Y.
We currently have a python script that downloads the exact CMake minimum and tests our project against it. This helps catch problems every once in a while.
Is there a more elegant way to handle this problem with GitHub actions? Having a custom python script isn't ideal. Also downloading CMake like this is a bit slow since it's not cached by GitHub actions.

get-cmake suggestion works beautifully!
Here is my implementation FWIW to future readers:
test-cmake-minimum:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- uses: lukka/get-cmake#latest
with:
cmakeVersion: 3.10.2
- name: Create build directory
run: mkdir build/
- name: Run CMake
working-directory: ./build
run: cmake ../
- name: Build
run: cmake --build build/
Thanks to get-cmake for simplifying this!

Related

Gitlab CI: create dist folder inside repository?

I just recently started using gitlab CI to automate some build/deploy steps. It works perfectly to build docker images etc, but I was wondering if it's possible to create a folder in the repository during a build step? For example I'm now making an npm utility package, but I'm just importing it in my other projects via a private gitlab repo (using deploy token), but the code of the util package is written in es6 and needs to be transpiled to commonJS to be used in the other packages. Manually I can run npm run build and it will output a dist folder with the transpiled code.
I was trying (and researching) if it's possible to automate this build process using .gitlab-ci but so far I couldn't find anything.
Anyone know how I can achieve this and/or if this is possible?
Thanks in advance!
Not sure if I got your question correctly, so add more details if not.
When your CI build creates new folders or files, they are written to the task runner's file system (no surprise here, I assume).
If you want to access these files from Gitlab's web UI you can define them as artifacts in your build job (see https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html)
Your build job would look something like that (pseudo code written by memory, not tested on Gitlab):
build:
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
UPDATE If you want to upload the build artifact to an NPM registry, you could just build and push together.
build:
script:
- npm run build
- npm publish <PARAMETERS>

Packaged published to npm is almost empty: Just publish README, LICENSE and package.json

I have a react component project created with nwb. I'm using Travis and semantic-release to make the releases.
But now, when I publish a new version, the package published from Travis is almost empty, and only have three files: README, LICENSE and package.json.
My .travis.yml configuration...
sudo: false
language: node_js
cache:
directories:
- ~/.npm
notifications:
email: false
node_js:
- '8'
before_install:
- npm install npm codecov.io coveralls
after_success:
- cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
- npm run travis-deploy-once "npm run semantic-release"
branches:
only:
- master
The travis build looks ok and I can't see any errors. It discovers the new version and publish it, but just publish those three files.
The public Github repository is this...
https://github.com/rigobauer/react-abc2svg
... and you can check the travis build here...
https://travis-ci.org/rigobauer/react-abc2svg/jobs/332199646
If I set a version number manually in package.json and run npm publish in my computer, then the package is published correctly.
I've tried cleaning npm caches, reinstalling all dependencies, recreating .travis.yml using semantic-release-cli setup, etc. But I always get the same result. When I try to upgrade or install the package in another project, the directory in node_modules only have those three files.
Any idea of where could be the problem?
UPDATED: I've recreated the project from scratch with nwb, reinstalling dependencies, etc. And I have the same problem.
UPDATED 2: I have the list of directories configured in package.json like this...
"files": [
"css",
"es",
"lib",
"umd"
]
... but I've also tried creating a .npmignore file. The problem persists.
Got it! Thanks to the semantic-release guys, I realize that I have to manually indicate to Travis to run my build script (generated with nwb). So just changing this to .travis.yml make it work...
.......
after_success:
- cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
- npm run build
- npm run travis-deploy-once "npm run semantic-release"
........
I thought that Travis was doing that automatically, because I have another component project made using the exactly same process, and that package was ok (and that's what was driving me crazy). After reading their answer, I re-check everything and realize that the I made the first publish of that package manually, and after that I incorporate semantic-release. The thing is that the next commits weren't related to feature or fix, so semantic-release doesn't generate a new release, and the original package was still there.
In case someone encounter the same type of issue, here is the Git issue with the answer: https://github.com/semantic-release/semantic-release/issues/615
I've found this in the Travis docs, maybe you should add the skip_cleanup: true option to your travis.yml (just a guess)

Support settings 2 languages in one travis ci file (objective-c and node for react-native)

I tried to run XCUITest (Objective-C/swift) on travis ci for a react-native project while there's also node jest unit tests that I'll be running. I was wondering what the best way is to set up the travis.yml file since XCUITest is in Objective-C and jest unit tests are in node_js. I've done some research but not sure what a good way to do it is.
It turns out the travis.yml file can be set up this way
language: objective-c
git:
submodules: false
sudo: required
services:
- docker
node_js:
- "5.10.1"
before_install:
- npm install
env:
- export NODE_VERSION="5.10.1"
script:
- npm test
- cd ios/ && xcodebuild test ...
hopefully it's useful to some people

Is there a CMake '--install' switch?

With reference to this question there is a so-called 'install' phase in CMake. I'm used to run CMake in a sequence that looks like this:
cmake ..
cmake --build . --config Debug
cmake --build . --config Release
Is there a cmake --install command line switch meant to be invoked after this?
Although I figure it is somehow related, I'm not looking for the so called install command here (I perceive this to be a function rather than a command, but this is likely a terminology issue).
No, this switch does not exist (until CMake 3.15, see my other answer).
If a project uses the install command, it generates the target install. You can call it with
cmake --build . --target install
This uses CMake's Build Tool Mode, which is an abstract interface for a couple of commands to the native build tool (e.g. make or Ninja) and can also be used to pass arbitrary arguments to the native build tool.
Beginning with version 3.15, CMake offers an install switch. From the release notes:
The "cmake(1)" command gained a new "--install" option. This may
be used after building a project to run installation without using
the generated build system or the native build tool.
Source: https://cmake.org/cmake/help/v3.15/release/3.15.html#id6
So you can use
cmake --install <dir> [--prefix <install-dir>]
The optional --prefix flag lets you override the CMAKE_INSTALL_PREFIX.

How to avoid reinstalling dependencies for each job in Gitlab CI

I'm using Gitlab CI 8.0 with gitlab-ci-multi-runner 0.6.0. I have a .gitlab-ci.yml file similar to the following:
before_script:
- npm install
server_tests:
script: mocha
client_tests:
script: karma start karma.conf.js
This works but it means the dependencies are installed independently before each test job. For a large project with many dependencies this adds a considerable overhead.
In Jenkins I would use one job to install dependencies then TAR them up and create a build artefact which is then copied to downstream jobs. Would something similar work with Gitlab CI? Is there a recommended approach?
Update: I now recommend using artifacts with a short expire_in. This is superior to cache because it only has to write the artifact once per pipeline whereas the cache is updated after every job. Also the cache is per runner so if you run your jobs in parallel on multiple runners it's not guaranteed to be populated, unlike artifacts which are stored centrally.
Gitlab CI 8.2 adds runner caching which lets you reuse files between builds. However I've found this to be very slow.
Instead I've implemented my own caching system using a bit of shell scripting:
before_script:
# unique hash of required dependencies
- PACKAGE_HASH=($(md5sum package.json))
# path to cache file
- DEPS_CACHE=/tmp/dependencies_${PACKAGE_HASH}.tar.gz
# Check if cache file exists and if not, create it
- if [ -f $DEPS_CACHE ];
then
tar zxf $DEPS_CACHE;
else
npm install --quiet;
tar zcf - ./node_modules > $DEPS_CACHE;
fi
This will run before every job in your .gitlab-ci.yml and only install your dependencies if package.json has changed or the cache file is missing (e.g. first run, or file was manually deleted). Note that if you have several runners on different servers, they will each have their own cache file.
You may want to clear out the cache file on a regular basis in order to get the latest dependencies. We do this with the following cron entry:
#daily find /tmp/dependencies_* -mtime +1 -type f -delete
EDIT: This solution was recommended in 2016. In 2021, you might consider the caching docs instead.
A better approach these days is to make use of artifacts.
In the following example, the node_modules/ directory is immediately available to the lint job once the build stage has completed successfully.
build:
stage: build
script:
- npm install -q
- npm run build
artifacts:
paths:
- node_modules/
expire_in: 1 week
lint:
stage: test
script:
- npm run lint
From docs:
cache: Use for temporary storage for project dependencies. Not useful for keeping intermediate build results, like jar or apk files. Cache was designed to be used to speed up invocations of subsequent runs of a given job, by keeping things like dependencies (e.g., npm packages, Go vendor packages, etc.) so they don’t have to be re-fetched from the public internet. While the cache can be abused to pass intermediate build results between stages, there may be cases where artifacts are a better fit.
artifacts: Use for stage results that will be passed between stages. Artifacts were designed to upload some compiled/generated bits of the build, and they can be fetched by any number of concurrent Runners. They are guaranteed to be available and are there to pass data between jobs. They are also exposed to be downloaded from the UI. Artifacts can only exist in directories relative to the build directory and specifying paths which don’t comply to this rule trigger an unintuitive and illogical error message (an enhancement is discussed at https://gitlab.com/gitlab-org/gitlab-ce/issues/15530 ). Artifacts need to be uploaded to the GitLab instance (not only the GitLab runner) before the next stage job(s) can start, so you need to evaluate carefully whether your bandwidth allows you to profit from parallelization with stages and shared artifacts before investing time in changes to the setup.
So, I use cache. When don't need to update de cache (eg. build folder in a test job), I use policy: pull (see here).
I prefer use cache because removes files when pipeline finished.
Example
image: node
stages:
- install
- test
- compile
cache:
key: modules
paths:
- node_modules/
install:modules:
stage: install
cache:
key: modules
paths:
- node_modules/
after_script:
- node -v && npm -v
script:
- npm i
test:
stage: test
cache:
key: modules
paths:
- node_modules/
policy: pull
before_script:
- node -v && npm -v
script:
- npm run test
compile:
stage: compile
cache:
key: modules
paths:
- node_modules/
policy: pull
script:
- npm run build
I think it´s not recommended because all jobs of the same stage could be executed in parallel.
First all jobs of build are executed in parallel.
If all jobs of build succeeds, the test jobs are executed in parallel.
If all jobs of test succeeds, the deploy jobs are executed in parallel.
If all jobs of deploy succeeds, the commit is marked as success.
If any of the previous jobs fails, the commit is marked as failed and no jobs of further stage are executed.
I have read that here:
http://doc.gitlab.com/ci/yaml/README.html
Solved a problem with a symbolic link to a folder outside the working directory. The solution looks like this:
//.gitlab-ci.yml
before_script:
- New-Item -ItemType SymbolicLink -Path ".\node_modules" -Target "C:\GitLab-Runner\cache\node_modules"
- yarn
after_script:
- (Get-Item ".\node_modules").Delete()
I know this is a enough dirty solution but it saves a lot of time for build process and extends the storage life.
GitLab introduced caching to avoid redownloading dependencies for each job.
The following Node.js example is inspired from the caching documentation.
image: node:latest
# Cache modules in between jobs
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- .npm/
before_script:
- npm ci --cache .npm --prefer-offline
server_tests:
script: mocha
client_tests:
script: karma start karma.conf.js
Note that the example uses npm ci. This command is like npm install, but designed to be used in automated environments. You can read more about npm ci in the documentation and the command line arguments you can pass.
For further information, check Caching in GitLab CI/CD and the cache keyword reference.