refactor(docker): make builds more repeatable

Remove things like build date and sha from app to improve build
repeatability and caching.
This commit is contained in:
Travis Shivers 2020-10-11 15:23:45 -05:00
parent c8e40204e6
commit 0624ab576d
No known key found for this signature in database
GPG Key ID: EE4CC2891B8FCD33
13 changed files with 71 additions and 144 deletions

View File

@ -28,10 +28,18 @@ jobs:
- name: Checkout
uses: actions/checkout@v2.3.3
- name: Repo metadata
id: repo
uses: actions/github-script@v3.0.0
with:
script: |
const repo = await github.repos.get(context.repo)
return repo.data
- name: Prepare
id: prep
run: |
echo ::set-output name=build-date::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.0.1
@ -84,11 +92,16 @@ jobs:
file: ./${{ matrix.dockerfile}}
platforms: ${{ steps.platforms.outputs.result }}
tags: ${{ matrix.docker-image }}:${{ github.sha }}
labels: |
org.opencontainers.image.title=${{ fromJson(steps.repo.outputs.result).name }}
org.opencontainers.image.description=${{ fromJson(steps.repo.outputs.result).description }}
org.opencontainers.image.url=${{ fromJson(steps.repo.outputs.result).html_url }}
org.opencontainers.image.source=${{ fromJson(steps.repo.outputs.result).clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.licenses=${{ fromJson(steps.repo.outputs.result).license.spdx_id }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
build-args: |
BUILD_DATE=${{ steps.prep.outputs.build-date }}
REVISION=${{ github.sha }}
- name: Inspect
run: |

View File

@ -128,10 +128,18 @@ jobs:
- name: Checkout
uses: actions/checkout@v2.3.3
- name: Repo metadata
id: repo
uses: actions/github-script@v3.0.0
with:
script: |
const repo = await github.repos.get(context.repo)
return repo.data
- name: Prepare
id: prep
run: |
echo ::set-output name=build-date::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.0.1
@ -193,12 +201,19 @@ jobs:
${{ matrix.docker-image }}:${{ needs.release-semantic.outputs.release-version }}
${{ matrix.docker-image }}:${{ needs.release-semantic.outputs.release-version-major }}.${{ needs.release-semantic.outputs.release-version-minor }}
${{ matrix.docker-image }}:${{ needs.release-semantic.outputs.release-version-major }}
labels: |
org.opencontainers.image.title=${{ fromJson(steps.repo.outputs.result).name }}
org.opencontainers.image.description=${{ fromJson(steps.repo.outputs.result).description }}
org.opencontainers.image.url=${{ fromJson(steps.repo.outputs.result).html_url }}
org.opencontainers.image.source=${{ fromJson(steps.repo.outputs.result).clone_url }}
org.opencontainers.image.version=${{ needs.release-semantic.outputs.release-version }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.licenses=${{ fromJson(steps.repo.outputs.result).license.spdx_id }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
build-args: |
VERSION=${{ needs.release-semantic.outputs.release-version }}
BUILD_DATE=${{ steps.prep.outputs.build-date }}
REVISION=${{ github.sha }}
- name: Update repo description
uses: peter-evans/dockerhub-description@v2.4.0

View File

@ -9,7 +9,6 @@ RUN SKIP_BUILD=true npm ci
COPY --chown=node:node . .
ARG VERSION
ARG REVISION
RUN npm run build
@ -25,14 +24,6 @@ RUN npm prune --production
# production environment
FROM node:14.13.1-alpine3.12 as production-stage
LABEL org.opencontainers.image.title="SyncLounge"
LABEL org.opencontainers.image.description="Enjoy Plex with your friends. In Sync. Together."
LABEL org.opencontainers.image.url="https://synclounge.tv"
LABEL org.opencontainers.image.source="https://github.com/synclounge/synclounge"
LABEL org.opencontainers.image.vendor="SyncLounge"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.documentation="https://docs.synclounge.tv"
RUN mkdir /app && chown -R node:node /app
WORKDIR /app
COPY --chown=node:node server.js .
@ -40,13 +31,4 @@ COPY --chown=node:node config config
COPY --chown=node:node --from=dependency-stage /app/node_modules node_modules
COPY --chown=node:node --from=build-stage /app/dist dist
ARG VERSION
LABEL org.opencontainers.image.version=$VERSION
ARG REVISION
LABEL org.opencontainers.image.revision=$REVISION
ARG BUILD_DATE
LABEL org.opencontainers.image.created=$BUILD_DATE
ENTRYPOINT ["/app/server.js"]

View File

@ -10,27 +10,9 @@ COPY --chown=node:node . .
ARG SERVERS
ARG VERSION
ARG REVISION
RUN npm run build
# production environment
FROM nginx:1.19.3-alpine as production-stage
LABEL org.opencontainers.image.title="SyncLounge Web"
LABEL org.opencontainers.image.description="Enjoy Plex with your friends. In Sync. Together."
LABEL org.opencontainers.image.url="https://synclounge.tv"
LABEL org.opencontainers.image.source="https://github.com/synclounge/synclounge"
LABEL org.opencontainers.image.vendor="SyncLounge"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.documentation="https://docs.synclounge.tv"
COPY --chown=nginx:nginx --from=build-stage /app/dist /usr/share/nginx/html
ARG VERSION
LABEL org.opencontainers.image.version=$VERSION
ARG REVISION
LABEL org.opencontainers.image.revision=$REVISION
ARG BUILD_DATE
LABEL org.opencontainers.image.created=$BUILD_DATE
COPY --chown=nginx:nginx --from=build-stage /app/dist /usr/share/nginx/html

30
package-lock.json generated
View File

@ -4332,11 +4332,21 @@
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.2",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.4.0"
},
"dependencies": {
"fsevents": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
"dev": true,
"optional": true
}
}
},
"chownr": {
@ -6026,15 +6036,6 @@
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
"dev": true
},
"dotgitconfig": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/dotgitconfig/-/dotgitconfig-1.1.1.tgz",
"integrity": "sha512-gkaAQMmhlE7N6NYtvckQ32f/xTX6Hv7RTtF9qKCYJEQgL/d6zJZk/D0eLFuuGPRCbpRj2PR/HcBLxtIh3MSB6Q==",
"dev": true,
"requires": {
"ini": "^1.3.5"
}
},
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@ -9158,15 +9159,6 @@
"integrity": "sha512-eYboRV94Vco725nKMlpkn3nV2+96p9c3gKXRsYqAJSswSENvBhN7n5L+uDhY58xQa0UukWsDMTGELzmD8Q+wTA==",
"dev": true
},
"last-commit-log": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/last-commit-log/-/last-commit-log-3.0.4.tgz",
"integrity": "sha512-NwvGT6O3eiOIALwxa/i1YcVgQuLO7w/KheP3wORmB2JM9IaG47PbkSAn2BZMa8Z8hkPYblY+awD4lFjHFFsQ9g==",
"dev": true,
"requires": {
"dotgitconfig": "^1.1.0"
}
},
"launch-editor": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz",
@ -15402,6 +15394,7 @@
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.8.tgz",
"integrity": "sha512-oouKUQWWHbSihqSD7mhymGPX1OQ4hedzAHyvm8RdyHh6m3oIvoRF+NM45i/bhNOlo8jCnuJhaSUf/6oDjv978g==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
@ -15413,6 +15406,7 @@
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",

View File

@ -43,7 +43,6 @@
"eslint-plugin-vue": "^7.0.1",
"fast-xml-parser": "^3.17.4",
"husky": "^4.3.0",
"last-commit-log": "^3.0.4",
"lint-staged": "^10.4.0",
"mux.js": "^5.6.4",
"sass": "^1.27.0",
@ -78,4 +77,4 @@
"engines": {
"node": ">=12"
}
}
}

View File

@ -159,7 +159,9 @@
<script>
import './assets/css/style.css';
import { mapActions, mapGetters, mapMutations } from 'vuex';
import {
mapActions, mapGetters, mapMutations, mapState,
} from 'vuex';
import redirection from '@/mixins/redirection';
import clipboard from '@/mixins/clipboard';
import linkWithRoom from '@/mixins/linkwithroom';
@ -193,8 +195,6 @@ export default {
'GET_SNACKBAR_OPEN',
'GET_BACKGROUND',
'GET_NAVIGATE_TO_PLAYER',
'GET_REPOSITORY_URL',
'GET_DISCORD_URL',
'GET_NAVIGATE_HOME',
]),
@ -220,17 +220,22 @@ export default {
'GET_PASSWORD',
]),
...mapState([
'repositoryUrl',
'discordUrl',
]),
links() {
return [
{
title: 'Github',
href: this.GET_REPOSITORY_URL,
href: this.repositoryUrl,
target: '_blank',
},
{
title: 'Discord',
target: '_blank',
href: this.GET_DISCORD_URL,
href: this.discordUrl,
},
];
},

View File

@ -64,12 +64,12 @@
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>v{{ GET_VERSION }}</v-list-item-title>
<v-list-item-title>v{{ version }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item
:href="GET_DISCORD_URL"
:href="discordUrl"
target="_blank"
>
<v-list-item-icon>
@ -82,7 +82,7 @@
</v-list-item>
<v-list-item
:href="GET_REPOSITORY_URL"
:href="repositoryUrl"
target="_blank"
>
<v-list-item-icon>
@ -109,30 +109,11 @@
</v-list-item>
</DonateDialog>
</v-list>
<template #append>
<v-divider />
<div
class="text-center pa-2"
style="opacity: 0.7; font-size: 12px;"
>
<div>
Build <a
class="text-decoration-none"
:href="GET_COMMIT_URL"
>
#{{ GET_GIT_HASH.substring(0, 7) }}
</a>
</div>
<div>Last updated {{ updatedAt }}</div>
</div>
</template>
</v-navigation-drawer>
</template>
<script>
import { mapGetters, mapMutations, mapState } from 'vuex';
import { formatDistanceToNow } from 'date-fns';
export default {
name: 'TheSidebarLeft',
@ -143,47 +124,26 @@ export default {
},
computed: {
...mapState(['isLeftSidebarOpen']),
...mapState([
'isLeftSidebarOpen',
'version',
'repositoryUrl',
'discordUrl',
]),
...mapGetters([
'GET_REPOSITORY_URL',
'GET_VERSION',
'GET_GIT_HASH',
'GET_DISCORD_URL',
'GET_RELEASE_URL',
'GET_COMMIT_URL',
]),
...mapGetters('plex', [
'GET_PLEX_USER',
]),
date() {
return new Date(parseInt(process.env.VUE_APP_GIT_DATE, 10) * 1000);
},
updatedAt() {
return `${formatDistanceToNow(this.date)} ago`;
},
},
methods: {
...mapMutations([
'SET_LEFT_SIDEBAR_OPEN',
]),
getTimeFromMs(ms) {
const hours = ms / (1000 * 60 * 60);
const absoluteHours = Math.floor(hours);
const h = absoluteHours > 9 ? absoluteHours : `0${absoluteHours}`;
const minutes = (hours - absoluteHours) * 60;
const absoluteMinutes = Math.floor(minutes);
const m = absoluteMinutes > 9 ? absoluteMinutes : `0${absoluteMinutes}`;
const seconds = (minutes - absoluteMinutes) * 60;
const absoluteSeconds = Math.floor(seconds);
const s = absoluteSeconds > 9 ? absoluteSeconds : `0${absoluteSeconds}`;
return `${h}:${m}:${s}`;
},
},
};
</script>

View File

@ -1,12 +1,5 @@
export default {
GET_VERSION: (state) => state.version,
GET_GIT_HASH: (state) => state.gitHash,
GET_REPOSITORY_URL: (state) => state.repositoryUrl,
GET_DISCORD_URL: (state) => state.discordUrl,
GET_RELEASE_URL: (state, getters) => `${getters.GET_REPOSITORY_URL}/releases/tag/v${
getters.GET_VERSION}`,
GET_COMMIT_URL: (state, getters) => `${getters.GET_REPOSITORY_URL}/commit/${
getters.GET_GIT_HASH}`,
GET_RELEASE_URL: (state) => `${state.repositoryUrl}/releases/tag/v${state.version}`,
GET_BACKGROUND: (state) => state.background,
GET_UP_NEXT_POST_PLAY_DATA: (state) => state.upNextPostPlayData,
GET_CONFIG: (state) => state.configuration,

View File

@ -31,7 +31,7 @@ export default {
GET_PLEX_INITIAL_AUTH_PARAMS: (state, getters, rootState, rootGetters) => ({
'X-Plex-Product': getters.GET_PLEX_PRODUCT_HEADER,
'X-Plex-Version': rootGetters.GET_VERSION,
'X-Plex-Version': rootState.version,
'X-Plex-Client-Identifier': getters.GET_CLIENT_IDENTIFIER,
'X-Plex-Platform': getters.GET_PLEX_PLATFORM_HEADER,
'X-Plex-Platform-Version': rootGetters.GET_BROWSER.version,
@ -58,7 +58,7 @@ export default {
GET_PLEX_AUTH_URL: (state, getters, rootState, rootGetters) => (code) => {
const urlParams = {
'context[device][product]': getters.GET_PLEX_PRODUCT_HEADER,
'context[device][version]': rootGetters.GET_VERSION,
'context[device][version]': rootState.version,
'context[device][platform]': getters.GET_PLEX_PLATFORM_HEADER,
'context[device][platformVersion]': rootGetters.GET_BROWSER.version,
'context[device][device]': getters.GET_PLEX_DEVICE_DEVICE_HEADER,

View File

@ -2,7 +2,6 @@ import { detect } from 'detect-browser';
const state = () => ({
version: process.env.VUE_APP_VERSION,
gitHash: process.env.VUE_APP_GIT_HASH,
repositoryUrl: 'https://github.com/synclounge/synclounge',
discordUrl: 'https://discord.gg/fKQB3yt',

View File

@ -61,7 +61,6 @@ export default {
computed: {
...mapGetters([
'GET_CONFIG',
'GET_REPOSITORY_URL',
]),
...mapGetters('plex', [

View File

@ -1,7 +1,4 @@
const path = require('path');
const LCL = require('last-commit-log');
const lcl = new LCL();
const config = require('./config');
@ -14,17 +11,6 @@ const pkgVersion = require('./package.json').version;
process.env.VUE_APP_VERSION = process.env.VERSION || pkgVersion;
try {
const lastCommit = lcl.getLastCommitSync();
process.env.VUE_APP_GIT_HASH = lastCommit.hash;
process.env.VUE_APP_GIT_DATE = lastCommit.committer.date;
} catch (e) {
// Sometimes on CI stuff they build with .git being present
// TODO: find better way to do this
process.env.VUE_APP_GIT_DATE = Math.floor(Date.now() / 1000);
process.env.VUE_APP_GIT_HASH = process.env.REVISION;
}
module.exports = {
// Relative publicPath to support subfolders
publicPath: '',