Skip to content

Commit

Permalink
SC-9516: Configure NPM and Node version from deploy.*.yaml (spryker#337)
Browse files Browse the repository at this point in the history
* SC-9516: implemented Node and NPM version configuration

* SC-9516: clean code + added validation rule

* SC-9516: clean code

* Update 02-deploy.file.reference.v1.md

SC-9516: updated doc

* Update 02-deploy.file.reference.v1.md

Co-authored-by: Andrii Tserkovnyi <andrii.tserkovnyi@spryker.com>
  • Loading branch information
zyuzka and andriitserkovnyi committed Jul 7, 2022
1 parent a0e198a commit e9ebb66
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 11 deletions.
3 changes: 3 additions & 0 deletions bin/sdk/images/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ function Images::_buildApp() {
--build-arg "KNOWN_HOSTS=${KNOWN_HOSTS}" \
--build-arg "SPRYKER_BUILD_HASH=${SPRYKER_BUILD_HASH:-"current"}" \
--build-arg "SPRYKER_BUILD_STAMP=${SPRYKER_BUILD_STAMP:-""}" \
--build-arg "SPRYKER_NODE_IMAGE_VERSION=${SPRYKER_NODE_IMAGE_VERSION}" \
--build-arg "SPRYKER_NODE_IMAGE_DISTRO=${SPRYKER_NODE_IMAGE_DISTRO}" \
--build-arg "SPRYKER_NPM_VERSION=${SPRYKER_NPM_VERSION}" \
"${DEPLOYMENT_PATH}/context" 1>&2

docker build \
Expand Down
20 changes: 20 additions & 0 deletions docs/07-deploy-file/02-deploy.file.reference.v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,25 @@ image:
```
***

### image: node:

Defines Node.js settings.

* `image: node: version:` - defines a Node.js version. Supports only major versions that are greater than the default one. The default version is `12`.
* `image: node: npm` - defines an NPM version. Supports only major versions that are greater than the default one. The default version is `6`.
* `image: node: distro:` - defines a Linux distribution for the Node Docker image. Should be equal to your base PHP image. Possible values are `alpine` and `debian`. This variable is optional with the default value of `alpine`.

```yaml
image:
...
node:
version: 18
distro: alpine
npm: 8
```
***


### image: php:

Defines PHP settings for Spryker applications.
Expand All @@ -280,6 +299,7 @@ image:
- tideways
```
***

### assets:

Defines the setting of *Assets*.
Expand Down
12 changes: 12 additions & 0 deletions generator/deploy-file-generator/config/validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ image.php:
array-type:
image.php.enabled-extensions:
array-type:
image.node.version:
integer-type:
range-value:
- 12
image.node.distro:
only-value:
- alpine
- debian
image.node.npm:
integer-type:
range-value:
- 6

# Assets
assets.image:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,27 @@ public function isValid(string $validateField, array $data): bool
return true;
}

return !($data < $this->ruleConfig[0] || $data > $this->ruleConfig[1]);
if ($data < $this->ruleConfig[0]) {
return false;
}

if (array_key_exists(1, $this->ruleConfig) && $data > $this->ruleConfig[1]) {
return false;
}

return true;
}

foreach ($data as $range) {
if (!is_int($range)) {
continue;
}

if ($range > $this->ruleConfig[0] || $range < $this->ruleConfig[1]) {
if ($range < $this->ruleConfig[0]) {
return false;
}

if (array_key_exists(1, $this->ruleConfig) && $range > $this->ruleConfig[1]) {
return false;
}
}
Expand All @@ -68,6 +80,6 @@ public function isValid(string $validateField, array $data): bool
*/
public function getValidationMessage(string $fieldName): string
{
return sprintf(static::VALIDATION_MESSAGE_TEMPLATE, $fieldName, $this->ruleConfig[0] . '...' . $this->ruleConfig[1]);
return sprintf(static::VALIDATION_MESSAGE_TEMPLATE, $fieldName, $this->ruleConfig[0] . '...' . $this->ruleConfig[1] ?? '');
}
}
66 changes: 65 additions & 1 deletion generator/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use DeployFileGenerator\DeployFileGeneratorFactory;
use DeployFileGenerator\Transfer\DeployFileTransfer;
use Spatie\Url\Url;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Yaml\Parser;
use Twig\Environment;
use Twig\Loader\ChainLoader;
Expand Down Expand Up @@ -156,6 +155,19 @@ public function setIsActive(bool $isActive): void
GLUE_BACKEND => 'GlueBackend',
];

const DEBIAN_DISTRO_NAME = 'bullseye';
const ALPINE_DISTRO_NAME = 'alpine';

const SPRYKER_NODE_IMAGE_DISTRO_ENV_NAME = 'SPRYKER_NODE_IMAGE_DISTRO';
const SPRYKER_NODE_IMAGE_VERSION_ENV_NAME = 'SPRYKER_NODE_IMAGE_VERSION';
const SPRYKER_NPM_VERSION_ENV_NAME = 'SPRYKER_NPM_VERSION';

const DEFAULT_NODE_VERSION = 12;
const DEFAULT_NODE_DISTRO = ALPINE_DISTRO_NAME;
const DEFAULT_NPM_VERSION = 6;

$projectData['_node_npm_config'] = buildNodeJsNpmBuildConfig($projectData);

foreach ($projectData['groups'] ?? [] as $groupName => $groupData) {
foreach ($groupData['applications'] ?? [] as $applicationName => $applicationData) {
foreach ($applicationData['endpoints'] ?? [] as $endpoint => $endpointData) {
Expand Down Expand Up @@ -1580,3 +1592,55 @@ function isArmArchitecture(): bool

return in_array($currentArchitecture, $possibleValue);
}

/**
* @param array $projectData
*
* @return array
*/
function buildNodeJsNpmBuildConfig(array $projectData): array
{
$imageName = $projectData['image']['tag'];
$nodejsConfig = $projectData['image']['node'] ?? [];

return [
SPRYKER_NODE_IMAGE_DISTRO_ENV_NAME => getNodeDistroName($nodejsConfig, $imageName),
SPRYKER_NODE_IMAGE_VERSION_ENV_NAME => array_key_exists('version', $nodejsConfig)
? (int)$nodejsConfig['version']
: DEFAULT_NODE_VERSION,
SPRYKER_NPM_VERSION_ENV_NAME => array_key_exists('npm', $nodejsConfig)
? (int)$nodejsConfig['npm']
: DEFAULT_NPM_VERSION,
];
}

/**
* @param array $nodejsConfig
* @param string $imageName
*
* @return string
*/
function getNodeDistroName(array $nodejsConfig, string $imageName): string
{
if (array_key_exists('distro', $nodejsConfig)) {
if ($nodejsConfig['distro'] == 'debian') {
return DEBIAN_DISTRO_NAME;
}

if ($nodejsConfig['distro'] == 'alpine') {
return ALPINE_DISTRO_NAME;
}
}

$imageData = explode('/', $imageName);

if ($imageData[0] !== 'spryker') {
return DEFAULT_NODE_DISTRO;
}

if (str_contains($imageData[1], 'debian')) {
return DEBIAN_DISTRO_NAME;
}

return ALPINE_DISTRO_NAME;
}
5 changes: 5 additions & 0 deletions generator/src/templates/deploy.bash.twig
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ readonly SPRYKER_REPOSITORY_HASH="${SPRYKER_BUILD_HASH:-"$(git rev-parse --verif
{% include "service/" ~ engine ~ "/" ~ serviceName ~ ".bash.twig" ignore missing with _context %}
{% endfor %}

# NodeJS variables
{% for envName, envValue in _node_npm_config %}
readonly {{ envName }}="{{ "${%s:-%s}" | format(envName, envValue) }}"
{% endfor %}

# Variables from environment
SPRYKER_XDEBUG_ENABLE="$([ "${SPRYKER_XDEBUG_ENABLE}" == '1' ] && echo '1' || echo '')"
SPRYKER_XDEBUG_ENABLE_FOR_CLI=''
Expand Down
16 changes: 16 additions & 0 deletions images/common/application/Dockerfile.twig
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# syntax = docker/dockerfile:experimental
ARG SPRYKER_PLATFORM_IMAGE=spryker/php:7.3
ARG SPRYKER_NODE_IMAGE_VERSION
ARG SPRYKER_NODE_IMAGE_DISTRO

FROM node:${SPRYKER_NODE_IMAGE_VERSION}-${SPRYKER_NODE_IMAGE_DISTRO} AS node

ARG SPRYKER_NPM_VERSION

RUN npm install -g npm@${SPRYKER_NPM_VERSION}

FROM ${SPRYKER_PLATFORM_IMAGE} AS application-basic

ENV SPRYKER_IN_DOCKER=1
Expand Down Expand Up @@ -51,3 +60,10 @@ COPY --chown=spryker:spryker jenkins/jenkins.docker.xml.twig /home/spryker/jenki

# Build info
COPY --chown=spryker:spryker php/build.php /home/spryker/build.php

# NodeJS + NPM
COPY --from=node /usr/lib /usr/lib
COPY --from=node /usr/local/share /usr/local/share
COPY --from=node /usr/local/lib /usr/local/lib
COPY --from=node /usr/local/include /usr/local/include
COPY --from=node /usr/local/bin /usr/local/bin
7 changes: 0 additions & 7 deletions images/common/cli/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ ENV PATH=/data/vendor/bin:$PATH
RUN --mount=type=cache,id=aptlib,sharing=locked,target=/var/lib/apt \
--mount=type=cache,id=aptcache,sharing=locked,target=/var/cache/apt \
bash -c 'if [ ! -z "$(which apt)" ]; then apt update -y && apt install -y \
nodejs \
npm \
inotify-tools \
netcat-openbsd \
git \
Expand All @@ -33,14 +31,9 @@ RUN --mount=type=cache,id=aptlib,sharing=locked,target=/var/lib/apt \
apt update -y && apt install -y \
yarn \
; fi'
# Debian contains outdated NPM package
RUN --mount=type=cache,id=npm,sharing=locked,target=/root/.npm \
bash -c 'if [ ! -z "$(which apt)" ]; then npm install npm@^6.0.0 -g; fi'

RUN --mount=type=cache,id=apk,sharing=locked,target=/var/cache/apk mkdir -p /etc/apk && ln -vsf /var/cache/apk /etc/apk/cache && \
bash -c 'if [ ! -z "$(which apk)" ]; then apk update && apk add \
nodejs \
npm \
inotify-tools \
netcat-openbsd \
coreutils \
Expand Down

0 comments on commit e9ebb66

Please sign in to comment.