diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..a8776de75 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +secrets filter=git-crypt diff=git-crypt diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..bdad52c24 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,128 @@ +name: CI + +on: + workflow_call: + inputs: + registry: + description: OCI registry for image publishing + required: true + type: string + tag: + description: OCI image tag to use for publishing + required: true + type: string + secrets: + mail_server: + description: Server address for sending mail + required: true + mail_server_port: + description: Server port for sending mail + required: true + mail_targets: + description: Target addresses for sending mail + required: true + mail_username: + description: Username on the mail server + required: true + mail_password: + description: Password on the mail server + required: true + +jobs: + image: + runs-on: ubuntu-latest + defaults: + run: + working-directory: angular + permissions: + contents: read + packages: write + steps: + - name: Check out the repository + id: checkout + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Set up node + id: setup-node + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + with: + node-version: current + cache: npm + cache-dependency-path: angular/package-lock.json + + - name: Run clean install + id: npm-ci + run: npm ci + + - name: Run tests + id: npm-test + run: npm run test -- --browsers ChromeHeadless --no-watch --no-progress + + - name: Build the project + id: npm-build + run: npm run build -- --configuration production + + - name: Set up buildx plugin + id: setup-buildx + uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 + + - name: Log into registry ${{ inputs.registry }} as ${{ github.actor }} + id: docker-login + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + with: + registry: ${{ inputs.registry }} + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Extract metadata + id: docker-meta + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 + with: + images: ${{ inputs.registry }}/${{ github.repository }} + tags: | + type=raw,value=${{ inputs.tag }} + + - name: Build and push the image + id: docker-build-push + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 + with: + context: . + push: true + tags: ${{ steps.docker-meta.outputs.tags }} + labels: ${{ steps.docker-meta.outputs.labels }} + + - name: Retrieve the execution time + id: exec-time + if: always() + env: + GH_TOKEN: ${{ github.token }} + run: | + echo "time=$(gh api /repos/${{ github.repository }}/actions/runs/${{ github.run_id }} \ + --jq '(.updated_at | fromdate) - (.created_at | fromdate)')" >> "$GITHUB_OUTPUT" + + - name: Send summary + if: always() + uses: dawidd6/action-send-mail@2cea9617b09d79a095af21254fbcb7ae95903dde # v3.12.0 + with: + server_address: ${{ secrets.mail_server }} + server_port: ${{ secrets.mail_server_port }} + username: ${{ secrets.mail_username }} + password: ${{ secrets.mail_password }} + subject: GitHub Actions Job Summary for ${{ github.repository }} (${{ job.status }}) + to: ${{ secrets.mail_targets }} + from: GitHub Actions (on behalf of ${{ github.actor }}) + body: |- + Job status: ${{ job.status }}. + Workflow took approximately ${{ steps.exec-time.outputs.time }} seconds to execute. + Summary: + - Check out the repository: ${{ steps.checkout.outcome }} + - Set up node: ${{ steps.setup-node.outcome }} + - Run clean install: ${{ steps.npm-ci.outcome }} + - Run tests: ${{ steps.npm-test.outcome }} + - Build the project: ${{ steps.npm-build.outcome }} + - Set up buildx plugin: ${{ steps.setup-buildx.outcome }} + - Log into ${{ inputs.registry }} as ${{ github.actor }}: ${{ steps.docker-login.outcome }} + - Extract metadata: ${{ steps.docker-meta.outcome }} + - Build and push the image: ${{ steps.docker-build-push.outcome }} + - Retrieve the execution time: ${{ steps.exec-time.outcome }} + - Send summary via email: one can only hope diff --git a/.github/workflows/trigger.yaml b/.github/workflows/trigger.yaml new file mode 100644 index 000000000..74ce6b83e --- /dev/null +++ b/.github/workflows/trigger.yaml @@ -0,0 +1,43 @@ +name: Run CI on push + +on: + push: + branches: + - master + - feature/* + +jobs: + secrets: + runs-on: ubuntu-latest + outputs: + server: ${{ steps.secrets.outputs.MAIL_SERVER }} + port: ${{ steps.secrets.outputs.MAIL_SERVER_PORT }} + targets: ${{ steps.secrets.outputs.MAIL_TARGETS }} + username: ${{ steps.secrets.outputs.MAIL_USERNAME }} + password: ${{ steps.secrets.outputs.MAIL_PASSWORD }} + steps: + - name: Check out the repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Unlock secrets with git-crypt + uses: sliteteam/github-action-git-crypt-unlock@f99c0c6b60bb7ec30dcec033a8f0a3b3d48f21e1 # v1.3.0 + env: + GIT_CRYPT_KEY: ${{ secrets.GIT_CRYPT_KEY }} + + - name: Extract the unlocked secrets + id: secrets + run: | + cat secrets >> "$GITHUB_OUTPUT" + + ci: + uses: ./.github/workflows/ci.yaml + needs: secrets + with: + registry: ghcr.io + tag: latest + secrets: + mail_server: ${{ needs.secrets.outputs.server }} + mail_server_port: ${{ needs.secrets.outputs.port }} + mail_targets: ${{ needs.secrets.outputs.targets }} + mail_username: ${{ needs.secrets.outputs.username }} + mail_password: ${{ needs.secrets.outputs.password }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..f9f2bdb06 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.git-crypt/ +.idea/ +.vscode/ +git-crypt-key diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..2f9fb12ac --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,34 @@ +repos: + - repo: https://github.com/adrienverge/yamllint + rev: v1.35.1 + hooks: + - id: yamllint + + - repo: https://github.com/lyz-code/yamlfix + rev: 1.17.0 + hooks: + - id: yamlfix + args: [--config-file, .yamlfix.toml] + + - repo: https://github.com/petalmd/git-crypt-pre-commit + rev: v0.1 + hooks: + - id: git-crypt + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-added-large-files + - id: check-merge-conflict + - id: check-symlinks + - id: end-of-file-fixer + - id: forbid-new-submodules + - id: mixed-line-ending + - id: no-commit-to-branch + - id: trailing-whitespace + + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.10.0.1 + hooks: + - id: shellcheck + args: [--check-sourced] diff --git a/.yamlfix.toml b/.yamlfix.toml new file mode 100644 index 000000000..424ad87cf --- /dev/null +++ b/.yamlfix.toml @@ -0,0 +1,4 @@ +whitelines = 1 +section_whitelines = 1 +explicit_start = false +sequence_style = "keep_style" diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 000000000..ce61e8ea8 --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,11 @@ +extends: default + +yaml-files: + - '*.yaml' + - '*.yml' + - .yamllint + +rules: + comments: disable + document-start: disable + line-length: disable diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..fee747036 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +# Tagged as 1.27.2-alpine3.20 +# https://github.com/nginxinc/docker-nginx-unprivileged/pkgs/container/nginx-unprivileged/299640275?tag=1.27.2-alpine3.20 +FROM ghcr.io/nginxinc/nginx-unprivileged@sha256:add866cd510386edb5a7e878f6566ede993a374d6abfd1e653a49b6e74562e31 + +COPY ./nginx.conf /etc/nginx/nginx.conf +COPY ./angular/dist/angular-starter/browser/ /usr/share/nginx/html/ + +CMD ["nginx"] diff --git a/README.md b/README.md index ad8ba255d..dffb9668f 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Here is a working Angular live demo : https://angular.ganatan.com
@@ -59,7 +59,7 @@ git clone https://gitlab.com/ganatan/angular-react-starter.git # change directory cd angular-react-starter -cd angular +cd angular # install the repo with npm npm install @@ -68,7 +68,7 @@ npm install npm start ``` -in your browser go to [http://localhost:4200](http://localhost:4200) +in your browser go to [http://localhost:4200](http://localhost:4200) @@ -95,7 +95,7 @@ npm start ``` -in your browser go to [http://localhost:3000](http://localhost:3000) +in your browser go to [http://localhost:3000](http://localhost:3000) # [Node Quick start](#node-quick-start) @@ -121,7 +121,7 @@ npm start ``` -in your browser go to [http://localhost:5000](http://localhost:5000) +in your browser go to [http://localhost:5000](http://localhost:5000) # [Angular Tutorial](#angular-quick-start) @@ -143,9 +143,9 @@ Here is a step by step Tutorial : https://www.ganatan.com/tutorials/getting-sta ## Development * `npm run start` -* in your browser go to [http://localhost:4200](http://localhost:4200) +* in your browser go to [http://localhost:4200](http://localhost:4200) -## Production +## Production * `npm run build` ## Linter @@ -166,9 +166,9 @@ Here is a step by step Tutorial : https://www.ganatan.com/tutorials/getting-sta ## Development * `npm run start` -* in your browser go to [http://localhost:3000](http://localhost:3000) +* in your browser go to [http://localhost:3000](http://localhost:3000) -## Production +## Production * `npm run build` ## Linter @@ -188,9 +188,9 @@ Here is a step by step Tutorial : https://www.ganatan.com/tutorials/getting-sta ## Development * `npm run start` -* in your browser go to [http://localhost:5000](http://localhost:5000) +* in your browser go to [http://localhost:5000](http://localhost:5000) -## Production +## Production * `npm run build` ## Linter @@ -217,4 +217,3 @@ Here is a step by step Tutorial : https://www.ganatan.com/tutorials/getting-sta ## [Tutoriels React en français](#french-tutorials) - Installation - https://www.ganatan.com/tutorials/demarrer-avec-react - Tutoriels Etape par étape - https://www.ganatan.com/tutorials - diff --git a/angular/LICENSE b/angular/LICENSE index d3a987df8..e18c26332 100644 --- a/angular/LICENSE +++ b/angular/LICENSE @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. diff --git a/angular/README.md b/angular/README.md index e91c11a76..f47af655b 100644 --- a/angular/README.md +++ b/angular/README.md @@ -5,7 +5,7 @@ ### Developpement * `npm run start` -* in your browser [http://localhost:4200](http://localhost:4200) +* in your browser [http://localhost:4200](http://localhost:4200) ## Linter * `npm run lint` @@ -19,7 +19,7 @@ ### Production * `npm run serve` -* in your browser [http://localhost:4000](http://localhost:4000) +* in your browser [http://localhost:4000](http://localhost:4000) ### Author diff --git a/angular/eslint.config.js b/angular/eslint.config.js index 7558b47ec..fd5f218b2 100644 --- a/angular/eslint.config.js +++ b/angular/eslint.config.js @@ -2,7 +2,7 @@ const eslint = require("@eslint/js"); const tseslint = require("typescript-eslint"); const angular = require("angular-eslint"); - + module.exports = tseslint.config( { files: ["**/*.ts"], @@ -37,7 +37,7 @@ module.exports = tseslint.config( "id-length": "error", "newline-before-return": "error", "space-before-blocks": "error", - "no-alert": "error" + "no-alert": "error" }, }, { diff --git a/angular/nginx.conf b/angular/nginx.conf index 544b710f9..064d882d8 100644 --- a/angular/nginx.conf +++ b/angular/nginx.conf @@ -34,4 +34,4 @@ http { } } -} \ No newline at end of file +} diff --git a/angular/package.json b/angular/package.json index d7cf58907..9de9213e8 100644 --- a/angular/package.json +++ b/angular/package.json @@ -42,4 +42,4 @@ "typescript": "5.5.4", "typescript-eslint": "8.2.0" } -} \ No newline at end of file +} diff --git a/angular/server.js b/angular/server.js index ff66ad41f..3747c347f 100644 --- a/angular/server.js +++ b/angular/server.js @@ -12,4 +12,3 @@ const port = 4000; app.listen(port, () => { console.log(`Example app listening on port ${port}`) }) - diff --git a/angular/src/app/app.component.html b/angular/src/app/app.component.html index f51f01c06..85e2f1f57 100644 --- a/angular/src/app/app.component.html +++ b/angular/src/app/app.component.html @@ -259,4 +259,4 @@