diff --git a/.changeset/empirica-release.md b/.changeset/empirica-release.md new file mode 100644 index 00000000..3ab4e889 --- /dev/null +++ b/.changeset/empirica-release.md @@ -0,0 +1,12 @@ +--- +"@empirica/core": patch +--- + +Empirica proxy download was using hard links and it could break upgrades. It now uses copy for safety. +That does mean we are using up more space on disk, but it remain relatively minimal all things +considered. We might want to look into pruning old versions at some point, but it does not seem +critical at the moment since empirica binaries are not that large. + +We've also improved looking up the current project release version by looking for the .empirica +directory in parent directories. This is helpful in the case of export, which runs in subdirectory and +will not pick up the correct empirica version. diff --git a/.changeset/minor.template b/.changeset/minor.template new file mode 100644 index 00000000..ffa0b88b --- /dev/null +++ b/.changeset/minor.template @@ -0,0 +1,3 @@ +--- +"@empirica/core": minor +--- diff --git a/.changeset/patch.template b/.changeset/patch.template new file mode 100644 index 00000000..c3f79e56 --- /dev/null +++ b/.changeset/patch.template @@ -0,0 +1,3 @@ +--- +"@empirica/core": patch +--- diff --git a/.github/workflows/build_and_release.yml b/.github/workflows/build_and_release.yml index bda98d90..bf2b1282 100644 --- a/.github/workflows/build_and_release.yml +++ b/.github/workflows/build_and_release.yml @@ -219,7 +219,7 @@ jobs: - name: Publish API docs run: | - cd lib/@empirica/core + cd empirica/lib/@empirica/core npm i ./docs.sh mv docs ../../../../docsv2/api diff --git a/.github/workflows/on_push_proxy.yaml b/.github/workflows/on_push_proxy.yaml index 60d161f1..9f76cd67 100644 --- a/.github/workflows/on_push_proxy.yaml +++ b/.github/workflows/on_push_proxy.yaml @@ -16,7 +16,7 @@ jobs: proxy: name: Build and upload proxy runs-on: ubuntu-latest - if: github.repository == 'empiricaly/empirica' && github.event.pull_request.draft == false + if: github.repository == 'empiricaly/empirica' && github.ref == 'refs/heads/main' steps: - name: Checkout uses: actions/checkout@v2 diff --git a/cmds/proxy/cmd/root.go b/cmds/proxy/cmd/root.go index 75fc85d8..71e875f1 100644 --- a/cmds/proxy/cmd/root.go +++ b/cmds/proxy/cmd/root.go @@ -46,6 +46,10 @@ func root(args []string) error { return errors.Wrap(err, "get binary") } + log.Debug(). + Str("path", path). + Msg("proxy: chosen binary path") + c := exec.CommandContext(ctx, path, args...) c.Stderr = os.Stderr diff --git a/internal/build/exec.go b/internal/build/exec.go index 68e90af4..f1978140 100644 --- a/internal/build/exec.go +++ b/internal/build/exec.go @@ -33,12 +33,49 @@ const ( ) var ( - ErrBuildMissing = errors.New("build info missing") - ErrBuildEmpty = errors.New("build info empty") + ErrBuildMissing = errors.New("build info missing") + ErrBuildEmpty = errors.New("build info empty") + ErrEmpiricaDirNotFound = errors.New("empirica dir not found") ) func ReleaseFilePath() string { - return settings.EmpiricaDir + "/" + settings.BuildSelectionFile + return path.Join(settings.EmpiricaDir, settings.BuildSelectionFile) +} + +func FindReleaseFilePath() (string, error) { + p, err := FindEmpiricaDir() + if err != nil { + return "", err + } + + return path.Join(p, settings.BuildSelectionFile), nil +} + +func FindEmpiricaDir() (string, error) { + if _, err := os.Stat(settings.EmpiricaDir); err == nil { + return settings.EmpiricaDir, nil + } + + dir, err := os.Getwd() + if err != nil || dir == "/" { + return "", ErrEmpiricaDirNotFound + } + + dir = filepath.Dir(dir) + + for { + if dir == "/" { + break + } + + if _, err := os.Stat(dir + "/" + settings.EmpiricaDir); err == nil { + return dir + "/" + settings.EmpiricaDir, nil + } + + dir = filepath.Dir(dir) + } + + return "", ErrEmpiricaDirNotFound } const filePerm = 0o600 // -rw------- @@ -92,7 +129,12 @@ func BinaryVersion() (*Build, error) { Interface("build", build). Msg("proxy: using build from env var") } else { - content, err := ioutil.ReadFile(ReleaseFilePath()) + relPath, err := FindReleaseFilePath() + if err != nil { + return nil, ErrBuildMissing + } + + content, err := ioutil.ReadFile(relPath) if err != nil { if errors.Is(err, os.ErrNotExist) { log.Debug(). @@ -308,6 +350,11 @@ func DownloadBinary(build *Build, asProd bool) (string, error) { return "", errors.New("no new binary paths found") } + fileBytes, err := ioutil.ReadFile(resp.Filename) + if err != nil { + return "", errors.New("failed to read new binary") + } + for _, fileName := range binpaths { dst, err := filepath.Abs(fileName) if err != nil { @@ -319,7 +366,7 @@ func DownloadBinary(build *Build, asProd bool) (string, error) { return "", errors.Wrap(err, "create binary dir") } - if err := os.Link(resp.Filename, dst); err != nil { + if err = ioutil.WriteFile(dst, fileBytes, 0o750); err != nil { if errors.Is(err, os.ErrExist) { if err = os.Remove(dst); err != nil { return "", errors.Wrap(err, "remove old binary file")