diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index fa8876cf..064edb6f 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -5,24 +5,17 @@ on: branches: [master] pull_request: -jobs: - golangci-lint: - name: golangci-lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Run golangci-lint - uses: golangci/golangci-lint-action@v1 - with: - version: v1.27 +env: + GOLATEST: 1.14 - tests-upload-unix: - name: Run tests and upload build artifacts +jobs: + build-test-upload: + name: Build, run tests and upload build artifacts runs-on: ${{ matrix.os }} strategy: matrix: go: [1.14] - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] include: - go: 1.13 os: ubuntu-latest @@ -35,38 +28,33 @@ jobs: with: go-version: ${{ matrix.go }} - - name: Build + - name: Build Linux/macOS + if: startsWith(matrix.os, 'windows-') != true run: go build -i -ldflags "-s -w -X github.com/drakkan/sftpgo/version.commit=`git describe --always --dirty` -X github.com/drakkan/sftpgo/version.date=`date -u +%FT%TZ`" -o sftpgo + - name: Build Windows + if: startsWith(matrix.os, 'windows-') + run: | + $GIT_COMMIT = (git describe --always --dirty) | Out-String + $DATE_TIME = ([datetime]::Now.ToUniversalTime().toString("yyyy-MM-ddTHH:mm:ssZ")) | Out-String + go build -i -ldflags "-s -w -X github.com/drakkan/sftpgo/version.commit=$GIT_COMMIT -X github.com/drakkan/sftpgo/version.date=$DATE_TIME" -o sftpgo.exe + - name: Initialize data provider run: ./sftpgo initprovider + shell: bash - name: Run test cases using SQLite provider run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic - name: Upload to Codecov - if: ${{ matrix.go == '1.14' }} + if: ${{ matrix.go == env.GOLATEST && startsWith(matrix.os, 'windows-') != true }} uses: codecov/codecov-action@v1 with: file: ./coverage.txt fail_ci_if_error: false - - name: Prepare artifact - run: | - mkdir output - cp sftpgo output/ - cp sftpgo.json output/ - cp -r templates output/ - cp -r static output/ - - - name: Upload artifact - uses: actions/upload-artifact@v2 - with: - name: sftpgo-${{ matrix.os }}-go${{ matrix.go }} - path: output - - name: Run test cases using bolt provider - if: ${{ matrix.go == '1.14' }} + if: ${{ matrix.go == env.GOLATEST }} run: | go test -v ./config -covermode=atomic go test -v ./httpd -covermode=atomic @@ -76,36 +64,23 @@ jobs: SFTPGO_DATA_PROVIDER__NAME: 'sftpgo_bolt.db' - name: Run test cases using memory provider - if: ${{ matrix.go == '1.14' }} + if: ${{ matrix.go == env.GOLATEST }} run: go test -v ./... -covermode=atomic env: - SFTPGO_DATA_PROVIDER__DRIVER: memory - SFTPGO_DATA_PROVIDER__NAME: '' + SFTPGO_DATA_PROVIDER__DRIVER: memory + SFTPGO_DATA_PROVIDER__NAME: '' - tests-upload-windows: - name: Run tests and upload build artifact on Windows - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: 1.14 - - - name: Build + - name: Prepare artifacts Linux/macOS + if: startsWith(matrix.os, 'windows-') != true run: | - $GIT_COMMIT = (git describe --always --dirty) | Out-String - $DATE_TIME = ([datetime]::Now.ToUniversalTime().toString("yyyy-MM-ddTHH:mm:ssZ")) | Out-String - go build -i -ldflags "-s -w -X github.com/drakkan/sftpgo/version.commit=$GIT_COMMIT -X github.com/drakkan/sftpgo/version.date=$DATE_TIME" -o sftpgo.exe + mkdir output + cp sftpgo output/ + cp sftpgo.json output/ + cp -r templates output/ + cp -r static output/ - - name: Initialize data provider - run: .\sftpgo.exe initprovider - - - name: Run test cases using SQLite provider - run: go test -v ./... -coverprofile=coverage.txt -covermode=atomic - - - name: Prepare artifact + - name: Prepare artifacts Windows + if: startsWith(matrix.os, 'windows-') run: | mkdir output xcopy .\sftpgo.exe .\output @@ -115,27 +90,12 @@ jobs: mkdir output\static xcopy .\static .\output\static\ /E - - name: Upload artifact + - name: Upload artifacts uses: actions/upload-artifact@v2 with: - name: sftpgo-windows + name: sftpgo-${{ matrix.os }}-go${{ matrix.go }} path: output - - name: Run test cases using bolt provider - run: | - go test -v ./config -covermode=atomic - go test -v ./httpd -covermode=atomic - go test -v ./sftpd -covermode=atomic - env: - SFTPGO_DATA_PROVIDER__DRIVER: bolt - SFTPGO_DATA_PROVIDER__NAME: 'sftpgo_bolt.db' - - - name: Run test cases using memory provider - run: go test -v ./... -covermode=atomic - env: - SFTPGO_DATA_PROVIDER__DRIVER: memory - SFTPGO_DATA_PROVIDER__NAME: '' - tests-postgresql-mysql: name: Run test cases using PostgreSQL/MySQL data providers runs-on: ubuntu-latest @@ -203,3 +163,14 @@ jobs: SFTPGO_DATA_PROVIDER__PORT: 3307 SFTPGO_DATA_PROVIDER__USERNAME: sftpgo SFTPGO_DATA_PROVIDER__PASSWORD: sftpgo + + golangci-lint: + name: golangci-lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v1 + with: + version: v1.27 + args: --timeout=3m diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..315e35af --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,223 @@ +name: Release Workflow + +on: + push: + tags: 'v*' + +env: + GOVERSION: 1.14 + +jobs: + create-release: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + + - name: Save release upload URL + run: echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url.txt + shell: bash + + - name: 'Store release upload URL' + uses: actions/upload-artifact@v2 + with: + name: upload_url + path: ./upload_url.txt + + upload-src-with-deps: + name: Upload sources with dependencies + needs: create-release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GOVERSION }} + + - name: Get version + id: get_version + run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} + + - name: Prepare release + run: | + go mod vendor + echo "${SFTPGO_VERSION}" > VERSION.txt + tar cJvf sftpgo_${SFTPGO_VERSION}_src_with_deps.tar.xz * + env: + SFTPGO_VERSION: ${{ steps.get_version.outputs.VERSION }} + + - uses: actions/download-artifact@v2 + with: + name: upload_url + + - name: Get upload URL + id: upload_url + run: | + URL=$(cat upload_url.txt) + echo "::set-output name=url::${URL}" + shell: bash + + - name: Upload Release + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.upload_url.outputs.url }} + asset_path: ./sftpgo_${{ steps.get_version.outputs.VERSION }}_src_with_deps.tar.xz + asset_name: sftpgo_${{ steps.get_version.outputs.VERSION }}_src_with_deps.tar.xz + asset_content_type: application/x-xz + + build: + name: Build Release + needs: create-release + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v2 + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GOVERSION }} + + - name: Set up Python + if: startsWith(matrix.os, 'windows-') + uses: actions/setup-python@v2 + with: + python-version: 3.x + + - name: Build Linux/macOS + if: startsWith(matrix.os, 'windows-') != true + run: go build -i -ldflags "-s -w -X github.com/drakkan/sftpgo/version.commit=`git describe --always --dirty` -X github.com/drakkan/sftpgo/version.date=`date -u +%FT%TZ`" -o sftpgo + + - name: Build Windows + if: startsWith(matrix.os, 'windows-') + run: | + $GIT_COMMIT = (git describe --always --dirty) | Out-String + $DATE_TIME = ([datetime]::Now.ToUniversalTime().toString("yyyy-MM-ddTHH:mm:ssZ")) | Out-String + go build -i -ldflags "-s -w -X github.com/drakkan/sftpgo/version.commit=$GIT_COMMIT -X github.com/drakkan/sftpgo/version.date=$DATE_TIME" -o sftpgo.exe + + - name: Initialize data provider + run: ./sftpgo initprovider + shell: bash + + - name: Get version + id: get_version + run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} + shell: bash + + - name: Get OS name + id: get_os_name + run: | + if [ $MATRIX_OS == 'ubuntu-latest' ] + then + echo ::set-output name=OS::linux + elif [ $MATRIX_OS == 'macos-latest' ] + then + echo ::set-output name=OS::macOS + else + echo ::set-output name=OS::windows + fi + shell: bash + env: + MATRIX_OS: ${{ matrix.os }} + + - name: Build REST API CLI + if: startsWith(matrix.os, 'windows-') + run: | + python -m pip install --upgrade pip setuptools wheel + pip install requests + pip install pygments + pip install pyinstaller + pyinstaller --hidden-import="pkg_resources.py2_warn" --noupx --onefile examples\rest-api-cli\sftpgo_api_cli.py + + - name: Prepare release Linux/macOS + if: startsWith(matrix.os, 'windows-') != true + run: | + mkdir -p output/{init,examples/rest-api-cli,sqlite} + echo "For documentation please take a look here:" > output/README.txt + echo "" >> output/README.txt + echo "https://github.com/drakkan/sftpgo/blob/${SFTPGO_VERSION}/README.md" >> output/README.txt + cp LICENSE output/ + cp sftpgo output/ + cp sftpgo.json output/ + cp sftpgo.db output/sqlite/ + cp -r static output/ + cp -r templates output/ + if [ $OS == 'linux' ] + then + cp -r init/sftpgo.service output/init/ + else + cp -r init/com.github.drakkan.sftpgo.plist output/init/ + fi + cp examples/rest-api-cli/sftpgo_api_cli.py output/examples/rest-api-cli/ + cd output + tar cJvf sftpgo_${SFTPGO_VERSION}_${OS}_x86_64.tar.xz * + cd .. + env: + SFTPGO_VERSION: ${{ steps.get_version.outputs.VERSION }} + OS: ${{ steps.get_os_name.outputs.OS }} + + - name: Prepare release Windows + if: startsWith(matrix.os, 'windows-') + run: | + mkdir output + copy .\sftpgo.exe .\output + copy .\sftpgo.json .\output + copy .\sftpgo.db .\output + copy .\dist\sftpgo_api_cli.exe .\output + copy .\LICENSE .\output\LICENSE.txt + mkdir output\templates + xcopy .\templates .\output\templates\ /E + mkdir output\static + xcopy .\static .\output\static\ /E + iscc windows-installer\sftpgo.iss + env: + SFTPGO_ISS_VERSION: ${{ steps.get_version.outputs.VERSION }} + SFTPGO_ISS_DOC_URL: https://github.com/drakkan/sftpgo/blob/${{ steps.get_version.outputs.VERSION }}/README.md + + - uses: actions/download-artifact@v2 + with: + name: upload_url + + - name: Get upload URL + id: upload_url + run: | + URL=$(cat upload_url.txt) + echo "::set-output name=url::${URL}" + shell: bash + + - name: Upload Release Linux/macOS + if: startsWith(matrix.os, 'windows-') != true + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.upload_url.outputs.url }} + asset_path: ./output/sftpgo_${{ steps.get_version.outputs.VERSION }}_${{ steps.get_os_name.outputs.OS }}_x86_64.tar.xz + asset_name: sftpgo_${{ steps.get_version.outputs.VERSION }}_${{ steps.get_os_name.outputs.OS }}_x86_64.tar.xz + asset_content_type: application/x-xz + + - name: Upload Release Windows + if: startsWith(matrix.os, 'windows-') + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.upload_url.outputs.url }} + asset_path: ./sftpgo_windows_x86_64.exe + asset_name: sftpgo_${{ steps.get_version.outputs.VERSION }}_${{ steps.get_os_name.outputs.OS }}_x86_64.exe + asset_content_type: application/x-dosexec diff --git a/sftpd/sftpd_test.go b/sftpd/sftpd_test.go index 004c494f..53b98e55 100644 --- a/sftpd/sftpd_test.go +++ b/sftpd/sftpd_test.go @@ -348,11 +348,12 @@ func TestBasicSFTPHandling(t *testing.T) { func TestConcurrentLogins(t *testing.T) { usePubKey := true + numLogins := 50 u := getTestUser(usePubKey) + u.QuotaFiles = numLogins + 1 user, _, err := httpd.AddUser(u, http.StatusOK) assert.NoError(t, err) var wg sync.WaitGroup - numLogins := 50 testFileName := "test_file.dat" testFilePath := filepath.Join(homeBasePath, testFileName) testFileSize := int64(65535) diff --git a/sftpgo.iss b/windows-installer/sftpgo.iss similarity index 77% rename from sftpgo.iss rename to windows-installer/sftpgo.iss index 3d4ebcb2..c007b77c 100644 --- a/sftpgo.iss +++ b/windows-installer/sftpgo.iss @@ -1,12 +1,19 @@ -; Script used to generate SFTPGo's Windows setup -; You need to change the paths for the source files to match your environment - #define MyAppName "SFTPGo" -#define MyAppVersion "0.9.6.1" +#if GetEnv("SFTPGO_ISS_VERSION") != "" + #define MyAppVersion GetEnv("SFTPGO_ISS_VERSION") +#else + #define MyAppVersion "v0.0.0" +#endif #define MyAppURL "https://github.com/drakkan/sftpgo" +#define MyVersionInfo StringChange(MyAppVersion,"v","") +#if GetEnv("SFTPGO_ISS_DOC_URL") != "" + #define DocURL GetEnv("SFTPGO_ISS_DOC_URL") +#else + #define DocURL "https://github.com/drakkan/sftpgo/blob/master/README.md" +#endif #define MyAppExeName "sftpgo.exe" -#define MyAppDir "C:\Users\vbox\Desktop\sftpgo_setup" -#define MyOutputDir "C:\Users\vbox\Desktop" +#define MyAppDir "..\output" +#define MyOutputDir ".." [Setup] AppId={{1FB9D57F-00DD-4B1B-8798-1138E5CE995D} @@ -28,7 +35,7 @@ ArchitecturesInstallIn64BitMode=x64 PrivilegesRequired=admin ArchitecturesAllowed=x64 MinVersion=6.1 -VersionInfoVersion={#MyAppVersion} +VersionInfoVersion={#MyVersionInfo} [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" @@ -38,7 +45,7 @@ Source: "{#MyAppDir}\sftpgo.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\sftpgo.db"; DestDir: "{commonappdata}\{#MyAppName}"; Flags: onlyifdoesntexist uninsneveruninstall Source: "{#MyAppDir}\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\sftpgo.json"; DestDir: "{commonappdata}\{#MyAppName}"; Flags: onlyifdoesntexist uninsneveruninstall -Source: "{#MyAppDir}\examples\sftpgo_api_cli.exe"; DestDir: "{app}\examples"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyAppDir}\sftpgo_api_cli.exe"; DestDir: "{app}\examples\rest-api-cli"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyAppDir}\templates\*"; DestDir: "{commonappdata}\{#MyAppName}\templates"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyAppDir}\static\*"; DestDir: "{commonappdata}\{#MyAppName}\static"; Flags: ignoreversion recursesubdirs createallsubdirs @@ -50,8 +57,8 @@ Name: "{commonappdata}\{#MyAppName}\credentials"; Permissions: everyone-full [Icons] Name: "{group}\Web Admin"; Filename: "http://127.0.0.1:8080/web"; Name: "{group}\Service Control"; WorkingDir: "{app}"; Filename: "powershell.exe"; Parameters: "-Command ""Start-Process cmd \""/k cd {app} & {#MyAppName} service --help\"" -Verb RunAs"; Comment: "Install, start, stop, uninstall SFTPGo Service" -Name: "{group}\REST API CLI"; WorkingDir: "{app}\examples"; Filename: "{cmd}"; Parameters: "/k sftpgo_api_cli.exe --help"; Comment: "Manage users and connections" -Name: "{group}\Documentation"; Filename: "https://github.com/drakkan/sftpgo/blob/master/README.md"; +Name: "{group}\REST API CLI"; WorkingDir: "{app}\examples\rest-api-cli"; Filename: "{cmd}"; Parameters: "/k sftpgo_api_cli.exe --help"; Comment: "Manage users and connections" +Name: "{group}\Documentation"; Filename: "{#DocURL}"; Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" [Run]