diff --git a/.devcontainer/dev/Dockerfile b/.devcontainer/Dockerfile similarity index 58% rename from .devcontainer/dev/Dockerfile rename to .devcontainer/Dockerfile index f2789bf9898c..13b885e3fb04 100644 --- a/.devcontainer/dev/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,8 @@ -FROM registry.opensuse.org/opensuse/leap:15.5 -RUN zypper addrepo --no-gpgcheck https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Utils/openSUSE_Leap_15.5 systemsmanagement:uyuni:utils +# SPDX-FileCopyrightText: 2024 SUSE LLC +# +# SPDX-License-Identifier: Apache-2.0 +FROM registry.opensuse.org/opensuse/leap:15.6 +RUN zypper addrepo --no-gpgcheck https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Utils/openSUSE_Leap_15.6 systemsmanagement:uyuni:utils RUN zypper ref && \ zypper -n install \ java-17-openjdk-devel \ @@ -7,13 +10,19 @@ RUN zypper ref && \ rsync \ apache-ivy \ ant \ + ant-junit5 \ ant-junit \ servletapi5 \ cpio \ + python3-PyYAML \ + python3-pip \ spacecmd \ expect \ git \ curl \ + make \ + sudo \ + neovim \ wget && \ zypper -n install obs-to-maven yarn && \ zypper clean -a diff --git a/.devcontainer/dev/devcontainer.json b/.devcontainer/dev/devcontainer.json deleted file mode 100644 index 9892dd1cd475..000000000000 --- a/.devcontainer/dev/devcontainer.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "uyuni-dev-container", - "build": { "dockerfile": "Dockerfile" }, - "remoteEnv": { - "JAVA_HOME": "/usr/lib64/jvm/java-17-openjdk" - }, - "postCreateCommand": "cd /workspaces/uyuni && ant -f java/manager-build.xml ivy" - - // More info: https://containers.dev/implementors/json_reference/ -} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000000..2a7c8b43bb92 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,44 @@ +{ + "name": "uyuni-devcontainer", + "build": { "dockerfile": "Dockerfile" }, + + "remoteUser": "root", + "containerEnv": { + "JAVA_HOME": "/usr/lib64/jvm/java-17-openjdk", + "ANT_HOME": "/usr/share/ant" + }, + + "portsAttributes": { + "8001": { + "label": "Debug Taskomatic", + "onAutoForward": "notify" + }, + "8002": { + "label": "Debug Search Server", + "onAutoForward": "notify" + }, + + "8003": { + "label": "Debug Tomcat", + "onAutoForward": "notify" + } + }, + + "customizations": { + "vscode": { + "extensions": [ + "nickheap.vscode-ant", + "vscjava.vscode-java-debug", + "redhat.java", + "shengchen.vscode-checkstyle", + "SonarSource.sonarlint-vscode", + "vscjava.vscode-java-test", + "vscjava.vscode-maven", + "vscjava.vscode-java-dependency", + "intersystems.language-server" + ] + } + }, + + "postCreateCommand": "curl -fLo \"${XDG_DATA_HOME:-$HOME/.local/share}\"/nvim/site/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim && echo \"alias vim='nvim -u .devcontainer/init.vim'\" >> ~/.bashrc && nvim -u ${containerWorkspaceFolder}/.devcontainer/init.vim +PlugInstall +qall && cd ${containerWorkspaceFolder} && ant -f java/manager-build.xml ivy" +} diff --git a/.devcontainer/init.vim b/.devcontainer/init.vim new file mode 100644 index 000000000000..51b35b067bbd --- /dev/null +++ b/.devcontainer/init.vim @@ -0,0 +1,209 @@ +" SPDX-FileCopyrightText: 2024 SUSE LLC +" +" SPDX-License-Identifier: Apache-2.0 +syntax enable +set tabstop=4 +set expandtab +set number +set autoindent +set nocompatible +set mouse=a +set textwidth=0 +set formatoptions+=t +set formatoptions-=l +set linebreak +set wrap +set tags=./tags + +filetype off +call plug#begin() +Plug 'fatih/vim-go' +Plug 'Xuyuanp/nerdtree-git-plugin' +Plug 'tpope/vim-fugitive' +Plug 'craigemery/vim-autotag', {'branch':'master'} +Plug 'neoclide/coc.nvim', {'branch': 'release'} +Plug 'preservim/nerdtree', { 'on': 'NERDTreeToggle' } +Plug 'nvim-lua/plenary.nvim' +Plug 'BurntSushi/ripgrep' +Plug 'sharkdp/fd' +Plug 'nvim-treesitter/nvim-treesitter' +Plug 'nvim-tree/nvim-web-devicons' +Plug 'nvim-telescope/telescope.nvim', { 'tag': '0.1.6' } +call plug#end() + +" run go imports on file save +let g:go_fmt_command = "goimports" + +" automatically highlight variable your cursor is on +let g:go_auto_sameids = 0 + +let g:go_highlight_types = 1 +let g:go_highlight_fields = 1 +let g:go_highlight_functions = 1 +let g:go_highlight_function_calls = 1 +let g:go_highlight_operators = 1 +let g:go_highlight_extra_types = 1 +let g:go_highlight_build_constraints = 1 +let g:go_highlight_generate_tags = 1 + + +" Use tab for trigger completion with characters ahead and navigate +" NOTE: There's always complete item selected by default, you may want to enable +" no select by `"suggest.noselect": true` in your configuration file +" NOTE: Use command ':verbose imap ' to make sure tab is not mapped by +" other plugin before putting this into your config +inoremap + \ coc#pum#visible() ? coc#pum#next(1) : + \ CheckBackspace() ? "\" : + \ coc#refresh() +inoremap coc#pum#visible() ? coc#pum#prev(1) : "\" + +" Make to accept selected completion item or notify coc.nvim to format +" u breaks current undo, please make your own choice +inoremap coc#pum#visible() ? coc#pum#confirm() + \: "\u\\=coc#on_enter()\" + +function! CheckBackspace() abort + let col = col('.') - 1 + return !col || getline('.')[col - 1] =~# '\s' +endfunction + +" Use to trigger completion +if has('nvim') + inoremap coc#refresh() +else + inoremap coc#refresh() +endif + +" Use `[g` and `]g` to navigate diagnostics +" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list +nmap [g (coc-diagnostic-prev) +nmap ]g (coc-diagnostic-next) + +" GoTo code navigation +nmap gd (coc-definition) +nmap gy (coc-type-definition) +nmap gi (coc-implementation) +nmap gr (coc-references) + +" Use K to show documentation in preview window +nnoremap K :call ShowDocumentation() + +function! ShowDocumentation() + if CocAction('hasProvider', 'hover') + call CocActionAsync('doHover') + else + call feedkeys('K', 'in') + endif +endfunction + +" Highlight the symbol and its references when holding the cursor +autocmd CursorHold * silent call CocActionAsync('highlight') + +" Symbol renaming +nmap rn (coc-rename) + +" Formatting selected code +xmap f (coc-format-selected) +nmap f (coc-format-selected) + +augroup mygroup + autocmd! + " Setup formatexpr specified filetype(s) + autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') + " Update signature help on jump placeholder + autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') +augroup end + +" Applying code actions to the selected code block +" Example: `aap` for current paragraph +xmap a (coc-codeaction-selected) +nmap a (coc-codeaction-selected) + +" Remap keys for applying code actions at the cursor position +nmap ac (coc-codeaction-cursor) +" Remap keys for apply code actions affect whole buffer +nmap as (coc-codeaction-source) +" Apply the most preferred quickfix action to fix diagnostic on the current line +nmap qf (coc-fix-current) + +" Remap keys for applying refactor code actions +nmap re (coc-codeaction-refactor) +xmap r (coc-codeaction-refactor-selected) +nmap r (coc-codeaction-refactor-selected) + +" Run the Code Lens action on the current line +nmap cl (coc-codelens-action) + +" Map function and class text objects +" NOTE: Requires 'textDocument.documentSymbol' support from the language server +xmap if (coc-funcobj-i) +omap if (coc-funcobj-i) +xmap af (coc-funcobj-a) +omap af (coc-funcobj-a) +xmap ic (coc-classobj-i) +omap ic (coc-classobj-i) +xmap ac (coc-classobj-a) +omap ac (coc-classobj-a) + +" Remap and to scroll float windows/popups +if has('nvim-0.4.0') || has('patch-8.2.0750') + nnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\" + nnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\" + inoremap coc#float#has_scroll() ? "\=coc#float#scroll(1)\" : "\" + inoremap coc#float#has_scroll() ? "\=coc#float#scroll(0)\" : "\" + vnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\" + vnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\" +endif + +" Use CTRL-S for selections ranges +" Requires 'textDocument/selectionRange' support of language server +nmap (coc-range-select) +xmap (coc-range-select) + +" Add `:Format` command to format current buffer +command! -nargs=0 Format :call CocActionAsync('format') + +" Add `:Fold` command to fold current buffer +command! -nargs=? Fold :call CocAction('fold', ) + +" Add `:OR` command for organize imports of the current buffer +command! -nargs=0 OR :call CocActionAsync('runCommand', 'editor.action.organizeImport') + +" Add (Neo)Vim's native statusline support +" NOTE: Please see `:h coc-status` for integrations with external plugins that +" provide custom statusline: lightline.vim, vim-airline +set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')} + +" Mappings for CoCList +" Show all diagnostics +nnoremap a :CocList diagnostics +" Manage extensions +nnoremap e :CocList extensions +" Show commands +nnoremap c :CocList commands +" Find symbol of current document +nnoremap o :CocList outline +" Search workspace symbols +nnoremap s :CocList -I symbols +" Do default action for next item +nnoremap j :CocNext +" Do default action for previous item +nnoremap k :CocPrev +" Resume latest coc list +nnoremap p :CocListResume + +" Start NERDTree and put the cursor back in the other window. +autocmd VimEnter * NERDTree | wincmd p + +" Exit Vim if NERDTree is the only window remaining in the only tab. +autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif + +" Close the tab if NERDTree is the only window remaining in it. +autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif + +" If another buffer tries to replace NERDTree, put it in the other window, and bring back NERDTree. +autocmd BufEnter * if winnr() == winnr('h') && bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 | + \ let buf=bufnr() | buffer# | execute "normal! \w" | execute 'buffer'.buf | endif + +let g:go_build_tags = 'ptf,nok8s' diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 02fc0791554f..640111888591 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -21,6 +21,13 @@ After: - [ ] **DONE** +## Codespace + + +Check if you already have a running container clicking on [![Running CodeSpace](https://badgen.net/badge/Running/CodeSpace/green)](https://github.com/codespaces) + +[![Create CodeSpace](https://img.shields.io/badge/Create-CodeSpace-blue.svg)](https://codespaces.new/mbussolotto/uyuni) [![About billing for Github Codespaces](https://badgen.net/badge/CodeSpace/Price)](https://docs.github.com/en/billing/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) [![CodeSpace Billing Summary](https://badgen.net/badge/CodeSpace/Billing%20Summary)](https://github.com/settings/billing/summary) [![CodeSpace Limit](https://badgen.net/badge/CodeSpace/Spending%20Limit)](https://github.com/settings/billing/spending_limit) + ## Test coverage ℹ️ If a major new functionality is added, it is **strongly recommended** that tests for the new functionality are added to the Cucumber test suite - No tests: **add explanation** diff --git a/.github/workflows/prebuilt_devcontainer.yml b/.github/workflows/prebuilt_devcontainer.yml new file mode 100644 index 000000000000..3e3d4d0d1a81 --- /dev/null +++ b/.github/workflows/prebuilt_devcontainer.yml @@ -0,0 +1,46 @@ +# SPDX-FileCopyrightText: 2023 SUSE LLC +# +# SPDX-License-Identifier: Apache-2.0 + +name: 'pre-built devcontainer' +on: # rebuild any PRs and main branch changes + pull_request: + push: + branches: + - master + +jobs: + devcontainer-build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + packages: write + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v4 + + - name: Compute tag for devcontainer image + id: meta + run: | + tag=$(git rev-parse --short HEAD) + echo "tag=$tag" >> "$GITHUB_OUTPUT" + + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and release devcontainer + run: | + npm install -g @devcontainers/cli + devcontainer build \ + --workspace-folder . \ + --image-name ghcr.io/${{ github.repository }}/devcontainer:${{ steps.meta.outputs.tag }} \ + --image-name ghcr.io/${{ github.repository }}/devcontainer:latest \ + --push + env: + BUILDX_NO_DEFAULT_ATTESTATIONS: true diff --git a/.vscode/settings.json b/.vscode/settings.json index 63c84590b026..45080ae4f832 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,7 +21,22 @@ "-Dlog4j2.configurationFile=${workspaceFolder}/java/buildconf/test/log4j2.properties" ] }, + "java.project.referencedLibraries": [ + "${workspaceFolder}/java/lib/*.jar", + ], + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.formatOnSave": true, + "ant.buildFilenames": "java/manager-build.xml", "java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx8G -Xms2G -Xlog:disable", + + "java.configuration.runtimes": [ + { + "name": "JavaSE-17", + "path": "/usr/lib64/jvm/java-17-openjdk", + "default": true + }, + ], + "java.checkstyle.configuration": "${workspaceFolder}/java/buildconf/checkstyle.xml", "java.checkstyle.properties": { "checkstyle.cache.file": "${workspaceFolder}/java/build/checkstyle.cache.src",